Tips and Tricks for Code Golfing in Javascript

Since we have topics for this in C++ and Haskell, I thought maybe I’d start one in javascript.
Most of my personal tricks are general tricks lifted more or less directly from this great stackexchange thread, but I’ve come up with some cool ones, mostly specific to codingame.

// disclaimer : I jot down everything I can come up with, some will be pretty generic ,some more specific. Please feel free to elaborate, or tell me if some of these realy belong into a more generic one //

1.General tips
consider this fairly standard, beautifully presented js init code :

var array1 = readline().split(' '),
    array2 = readline().split(' '),
    somenumber = parseInt(array1[0]), someConstant = 0;
  • usuals appy here : one letter vars, no ;, … you know the drill
  • get rid of var, var is for the weak (and when you’re, you know, writing anything beyond golf)
  • CG doesn’t discard blank spaces anymore, so compress that baby! no indent, less newlines, as few spaces as possible
  • use implicit typecasting as much as possible! my favorite is +a instead of parseInt(a) but the stackexchange I linked has many good ones.
  • functions are variables too, alias the §h|t out of them! for example readline is very long so R=readline saves you loads of bytes, from the second call! for methods, store their name : c='charCodeAt',a=S1[c](0),b=S2[c](0),...
  • while you’re at it, cram as much as you can into unused function args, so a=0,b=readline() becomes b=readline(a=0) for a whole one byte saved, but much more if you get creative.

With just those in mind, the previous code can be reduced to r=readline,(x=>r().split(' '),B=f(A=f(C=0)),N=+A[0] which is much much shorter and an horrible nightmare for anyone that has maintained code they didn’t write…

2. take advantage of having an up-to date js environment : EC6 goodness!

  • destructuring assignment : [a,b,,d]=readline().split() // you can even skip values if you want!
  • lambdas, lambdas everywhere : someArray.map(x=>+x) //converts all values to numeric! (but really you shouldn’t have so many +es that you need this one
  • array.revert, array.reduce, Array.every, array.map are here for you, use them!
  • there are probably good tricks using comprehensions like A=[for(x of readline().split(' '))+x] but I haven’t come up with any for now. feel free to comment with some

3. a well written for trumps most while loops as seen in the first answer here
I use this one on almost every golf challenge in CG.

4. the ternary operator is almost like black magic or catnip
you probably know by now that a well written ternary can replace a if/else structure, but the fact that it also returns a value can make for very, very interesting scenarios.

  • for example, the smallest of 4 numbers is result=(x=(a<b?a:b))<(y=(c<d?c:d))?x:y (not the most useful I know)
  • but also you can discriminate what to send a function like `print(values[0]?values.reduce(…):“0”)

5. more tricks I’ve come up with

  • discriminate between strings via the char position accessor (or “one-letter-long substring”): for example if you want to know if S is “MyAlly” instead of “MyEnnemy” you could use S=="MyAlly", but we’re golfing here, so think more S[3]=="A", or even better : !S[6]
  • know about, and distort, truthiness! for example be aware that -1 and “0” are truthy values. so
    • the quickest way to test if a string s containing a number (as you will often have) is !+s
    • !!array.indexOf(thing) will not tell you that thing is somewhere in array, but !~array.indexOf(thing) will (cause ~-1 is 0, which I find weird)
  • use and abuse shortcircuiting!
    • for defaulting variable=S.match(/regexp/) || S=defaultCodeNotCalledIfMatch();
    • for branching `for(a in readline.split(’ '))+a&&print(a+“is not zer0!”);

6. please feel free to elaborate
I’m desperate to find ways to reduce the weight of my input loop (readline().split(’ ').map or sort or reduce). If you know about tricks, tell meeeeee! :slight_smile:

17 Likes

Maybe i’ll destroy everyone hope. But i don’t really like code golfing anyway.

There’s a pretty simple way to make very short javascript code : code it in bash. Just an example:

system('read n\nread t\necho $t');

system is a SpiderMonkey function to execute a system command line. Since we are on a linux, it’s the bash language. So let’s say you have a 40 characters bash solution in two lines, you can write this:

system('line1\nline2');

Most of the time, javascript can’t beat bash so you can’t find shorter.

7 Likes

Now for more specific javascript code golfing tips:

The double readline

Most of the time on CG, you have to read 2 inputs. One integer and one line of multiple integers (or string). The javascript doesn’t care of the first integer, but you have to read it anyway. The shortest way to read that 2 lines is this one:

r=readline
s=r(r())

Read multiple lines

An extension of the on above. If you have to read multiples lines, do this:

r=readline
for(r();s=r();)print(s)

Feel like hardcoding ?

Print a different answer according to a variable

print({1:45,5:85,'test':'bla'}[v]) 

The less you read, the shorter you are:

print({1:45,5:85,9:456}[readline()[0]]) 

You can do the same with a string

print('W E S N W'[readline()[0]])

How to print multiple lines at once

 print('line1\nline2\line3');

Works also with an array:

 print(['line1', 'line2'].join('\n'))

Javascript destructuring is pretty smart and lazy

Don’t be afraid to read to much, it won’t crash

[a,b,c,d]=readline().split(' ')

If the line if just "0 5", c and d will just be undefined, nothing will crash.

Do learn regexp

You can’t beat a regular expression in most clashes:

print(readline().match(/A-Z/))

Some others tricks

[i, array[i]] = "1 45";

i will be 1, and 45 will be put in array[1].

quit()

Use quit() to quit the program.

print(1,"test",78);

Will print 1 test 78

print(...[1, 'test', 78])

Will also print 1 test 78 (shorter than print([1, 'test', 78].join(' '))

print(readline()['to'+(b?'Lower':'Upper')+'Case']())

Shorter than a if

Use js compress

16 Likes

Thanks a lot @b_evieux and @Magus for that. Pretty bumed about the bash one since for me it’s a hack at the same level as hardcoding, but I knew it all along honestly :confused:

This post is full of great tips, keep doing that, the most important part are the ones specific to codingame aka readline and such, as they can’t be googled :wink:

Yeah, thanks @Magus, great tips! (btw I think your for loop has one ; too many.

About hardcoding, I’m really not a fan, to the tune that I’ve been avoiding to shave off 10bytes from my Thor code because I feel it would be hardcoding (my code could handle going north, even if it’s useles given the test cases). TBH I wish the validators would be random inside the boundaries of the puzzle.

one more tip I’ve used is that a sting of instruction,instruction,... returns it’s last instruction as a result, which is useful inside a ternary operator or a fancy for() :slightly_smiling:

Thanks. I fixed that.

Is Bash call (system) still a thing? Seems like it was removed, says “system is not defined”

Since codingame is using NodeJS instead of Spidermonkey, system does not exists anymore. You can still call a bash command, but the code to do that is much longuer.

Unicode compression trick:

eval(’’+Buffer(“JS code in utf16”,“ucs2”))

2 Likes

I had never tried that trick, but now that I discovered it and am trying, I’m pretty confident it’s now prevented.

It seems utf16 chars now count as two chars in code golfing challenges and shortest code clashes.

Am I correct or am I missusing this trick?

Works for me

Best techniques I know of:

  • Math.floor(x) is the same as x|0 which comes in very handy at times !
  • foo.split('bar') can always be replaced with foo.split`bar` which saves you two bytes :slight_smile:
    You can also use this on null or undefined to convert them to 0.
  • "ABCDEF".split('') (or "ABCDEF".split`` ;p) is the same as [..."ABCDEF"]
5 Likes