Open Source Your Knowledge, Become a Contributor
Technology knowledge has to be shared and made accessible for free. Join the movement.
JavaScript
(This page is contributed by Djoums)
Checking the sample code
Looking at the syntax
Let's check the above code for some characteristics of javascript (JS) syntax:
//...
Here we commented out the reading from input stream, and replaced it with a simple assignment.const m = 'CG'
- JS is an interpreted language with dynamically typed variables, which means we never give a type to any of our variables. Variables can even change their underlying type during the course of the program, although it is something you should always avoid, unless you have a very good reason to do so.
const
means read-only and preventsm
from being reassigned after its initialisation. It is generally a good practice to declare any variable withconst
whenever possible, as it can prevent bugs preemptively and help developers understand the flow of the code.'CG'
is a string but can also be declared as"CG"
, as long as your choice of quote is consistent, JS will oblige.
c = ['00', '0'];
- Since
c
is declared on the same line asm
, it also receives theconst
modifier. [ ]
indicates an array of elements, which in this case is an array containing two strings:'00'
and'0'
.;
at the end of a line is optional in JS and comes down to personal preference.
- Since
let b = '';
- Opposite to
const
islet
, which is an indication that this variable is going to see some change in your program. - Note that
var
is also usable instead oflet
, but it is an older version of it that is supported as a legacy.
- Opposite to
for (const w of m)
- A for-of loop allows you to iterate through a given iterable, in this case a string, which is an iterable of chars. You can of course do the same for an array.
- Curly braces
{ }
are optional for single statement instructions.
b += Number(w.charCodeAt(0)).toString(2).padStart(7, '0');
Several things are happening in this line, so let's go one by one:- We can concatenate strings with the
+
operator. The+
operator is overloaded by different types, meaning different operations will happen if the operands are strings or numbers for example. +=
is a shortcut for saying that b = b + somethingElse.w.charCodeAt(0)
is a function call that returns the ASCII code of the 0th character in a string, this code is a number..toString(2)
is another function call, that can be used on numbers to display them as a string. The2
is an optional parameter that indicates which base we want to display the number in, in this case 2 means as binary..padStart(7, '0')
is yet another (final) function call, that can be used on a string. It means that we want our string to be at least 7 characters long, and if it is not, then fill it with'0'
from the left until it is. For example101100
would become0101100
.
- We can concatenate strings with the
let a = c[b.charCodeAt(0) - '0'.charCodeAt(0)] + ' 0';
the only new thing in this line is referencing an array's elements using square brackets[ ]
. Arrays are 0 indexed.for (let i = 1; i < b.length; i++)
The typical C-style loop syntax. Sinceb
is a string, we can access its length by calling its property.length
.if (b[i] === b[i - 1])
- A straightforward equality comparison, except it is actually not. For historical reasons, the traditional
==
(equality operator) should pretty much never be used in JS, and be replaced with===
(identity operator). If you want to learn more about it, you can read a detailed explanation here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators - The ternary operator
? :
could have been also used here.
- A straightforward equality comparison, except it is actually not. For historical reasons, the traditional
console.log(a);
Writing to the console. We will need this a lot on CodinGame! :-)
Other characteristics
While not directly visible from the above code snippet, there are some other important aspects of JS worth noting :
- As an interpreted language, JS needs an engine to be executed. When navigating on the web, this is done by your browser, and since this is a major part of web pages now, all those engines have been very optimized. V8 is the most used engine, as all the chromium based browsers depend on it, as well as Node.js and the applications built with Electron.
- JS uses garbage collection, so you don't have to manually manage memory. In fact you can't, even if you wanted to, there's no syntax or keyword that would allow you to.
- JS has a single
Number
type, no int/float/double to be seen here, all the same! This format makes things simpler but has some drawbacks:- Numbers have a double-precision 64 bits representation, which is fine for many uses but will fail for some. In particular, the maximum exponent attainable for an integer value is 53 in this format, meaning that the maximum integer value for a JS number is
2^53 - 1
. Whereas formats likelong
in other languages can go up to2^63 - 1
. This can easily cause trouble in CodinGame puzzles and is a limitation authors should keep in mind. - Numbers being 64 bits by default means you have no control over their memory consumption, there's no way to declare a 16 or 32 bits integer for example.
- Numbers have a double-precision 64 bits representation, which is fine for many uses but will fail for some. In particular, the maximum exponent attainable for an integer value is 53 in this format, meaning that the maximum integer value for a JS number is
- JS can be very strong when it comes to functional programming. Functions are treated as any other objects, a principle often called functions as first class citizens.
- There are many advanced language features we cannot address in this intro, such as interfaces, inheritance, delegates, currying etc.
- One of the infamous characteristics of JS is the complete freedom it gives to the developer. It is so flexible and accepting that you can write pretty much anything, from the awesome to the horrendous. To mitigate this issue and add consistency, TypeScript (TS) was created, as a superset of JS. It means your TS code is transpiled into regular JS before running.
- Generics are not supported in JS, however TS adds that feature.
Embracing the functional freedom
Let's revisit our initial code to take advantage of both the freedom and the functional strength of JS.
As you can see, our code is now a one-liner! Albeit a long one :-) We can do so by chaining function calls and construct a single complex query, operation by operation. Let's analyze this new code.
.split('')
splits a string using the given argument as a separator. In this case it is empty, so the function will separate all characters of the string and return an array of chars..map(c => ('0' + c.charCodeAt(0).toString(2)).slice(-7))
map
is a tranformative function, it is called on a array and returns another array. It takes a function as a parameter, which will be applied to every element of the initial array, in order to create the resulting array. For example if you had[1, 2, 3]
and you called.map(i => i + 1)
on it, you would get[2, 3, 4]
as the output. Note that the output is a new array, leaving the original untouched..map(c => ...)
makes use of lambda functions, which are inlined anonymous functions. You can create a regular function and pass it as an argument to themap
call, but in this case we simply declare it on the fly.'0' + c.charCodeAt(0).toString(2)
has been covered in the initial code, nothing new here..slice(-7)
is a neat trick.slice
is a function that returns a subrange from an array or a string, by giving it a starting index and an ending index (optional). By using-7
as the starting index, we're telling the program to take the last 7 characters. Combined with the added'0'
in front ofc.charCodeAt(0).toString(2)
, this replaces the call to.padStart
that we used initially. It isn't better or worse per se, simply different for demonstration purposes.
.join('')
can be called on an array to create a string representation of it, using the parameter as an element separator. In this case it is empty, so all the elements will be concatenated directly. The elements are converted into strings themselves in the process, by calling the default.toString()
function on each one.match(/(.)\1*/g)
is the most complex line here.- This is a call to a regular expression, which is a powerful tool to parse/analyze strings. Powerful but intimidating, because of its very specific syntax and potential complexity. If you want to learn more, you can look at the following guide: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
- Without going into to much details, this regular expression will split a given string into chunks of the same value, for example the string
10001100
would become['1', '000', '11', '00']
.
.map(c => ['00 ','0 '][c[0]] + '0'.repeat(c.length))
: another transformative call['00 ','0 '][c[0]]
is a small example of the freedom of JS. Herec[0]
is a string, yet we directly use it to access an array by index. No worries, JS will recognize at runtime that it should be a number and interpret the string as such (if it is not a number, bad things can ensue :-)).'0'.repeat(c.length)
is straightforward, repeat'0'
by the given count and make a string as a result.
.join(' ')
our final call. We saw this one earlier but this time we're asking for a space to be inserted between each element of the array.
Resources to check
Coming next...
In the above Javascript article we have already seen some functional programming in action. Let's dive into this subject even deeper, and visit F#!