21

I'm trying to understand how this palindrome expression is giving 42. I know about operator precedence rules, but this is beyond my current Javascript level. How can I start?

alert ("The answer is " +

[(0>>(0==0))+([0]+[(0==0)+(0==0)]^0)]*[(0^[(0==0)+(0==0)]+[0])+((0==0)<<0)]

);
Code Maverick
  • 20,171
  • 12
  • 62
  • 114
user3097261
  • 213
  • 2
  • 5

2 Answers2

18

The basic elements are as follows:

0==0

This is true, which can be coerced in to 1.

a >> b

The right-shift operator. In this case, it's only used at the beginning of the expression as 0 >> 1 which evaluates to 0.

a^b

Bitwise XOR. Both usages above have either a or b are 0, and so the result is the non-zero operand, coerced into an integer.

[a] + [b]

String addition of a and b, evaluates to "ab"; if both a and b are numeric (e.g. [0]+[1] the result can be coerced into a numeric.

[a] * [b]

Multiplication can be performed on single element arrays, apparently. So this is equivalent to a*b.

Finally,

a << b

The left-shift operator; for positive integers this effectively multiplies by 2 to the power of b. In the expression above, this is used with b = 0, so the result is a, coerced into an integer.

If you apply the correct order of operations, you get out [2] * [21] which evaluates to 42.

Jeremy
  • 2,642
  • 18
  • 36
  • You're welcome. I believe, that in this case Bitwise XOR is used to cast string into number type. – Givi Dec 12 '13 at 22:28
11

[(0>>(0==0))+([0]+[(0==0)+(0==0)]^0)]*[(0^[(0==0)+(0==0)]+[0])+((0==0)<<0)] === 42 because

  • (0>>(0==0))+([0]+[(0==0)+(0==0)]^0) === 2 because

    • (0>>(0==0)) === 0 because
      • (0==0) === true
      • (0>>true) === 0 (true coerced into 1)
    • ([0]+[(0==0)+(0==0)]^0) === 2 because
      • (0==0)+(0==0) === 2
      • [0]+[2] === '02'
      • '02'^0 === 2 ('02' coerced into 2)
  • (0^[(0==0)+(0==0)]+[0])+((0==0)<<0) === 21 because

    • (0^[(0==0)+(0==0)]+[0]) === 20 because

      • (0==0)+(0==0) === 2
      • [2]+[0] === '20'
      • 0^'20' === 20 ('20' coerced into 20)
    • ((0==0)<<0) === 1 because

      • (0==0) === true
      • true<<0 === 1 (true coerced into 1)

The code uses three binary operators:

  • >> is the Bitwise Right Shift with Sign Operator:

    It moves all bits in its first operand to the right by the number of places specified in the second operand. The bits filled in on the left depend on the sign bit of the original operand, in order to preserve the sign of the result. If the first operand is positive, the result has zeros placed in the high bits; if the first operand is negative, the result has ones placed in the high bits. Shifting a value right one place is equivalent to dividing by 2 (discarding the remainder), shifting right two places is equivalent to integer division by 4, and so on.

  • << is the Bitwise Left Shift with Sign Operator:

    It moves all bits in its first operand to the left by the number of places specified in the second operand. New bits are filled with zeros. Shifting a value left by one position is equivalent to multiplying by 2, shifting two positions is equivalent to multiplying by 4, etc.

  • ^ is the Bitwise XOR Operator:

    It performs a Boolean exclusive OR operation on each bit of its integer arguments. Exclusive OR means that either operand one is true or operand two is true, but not both.

Information about binary operators taken from List of all binary operators in JavaScript and http://www.tutorialspoint.com/javascript/javascript_operators.htm.

Note that binary operators truncate floating-points.

Community
  • 1
  • 1
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • Might be worth noting that the shift operators truncate floating-points before shifting. – Jeremy Dec 12 '13 at 22:28
  • You have a typo **0^'20' === 20 ('02' coerced into 2)** should be **0^'20' === 20 ('20' coerced into 20)** – Givi Dec 12 '13 at 22:38