4
\$\begingroup\$

A game of 2048 goes like this:

  • Every move you get another piece - either 2 90% of the time, or 4 10% of the time
  • for each 2 equal pieces combined you get a piece of the sum of the two and the sum gets added to your score

Your task

given a board of a 4x4 game, give the average score of what A game like that would result in.

To calculate it, go the other way around of the game. For example, if there's an 8 piece, it's made from 4s. The average score of a 4 piece is 4*90% (90% of the time it's made from combining two 2 pieces together and it the other 10% a 4 isn't made, but ) = 3.6. As to make an 8 you need two 4s, and then you need to combine them to an 8, the result is 3.6*2 + 8 = 15.2.

In pseudocode a calculation for one number could be this:

function value (x) {
  if (x > 4) return value(x / 2) * 2 + x
  else if (x == 4) return 4*90%
  else return 0
}

but you're free to choose any approach as long as it works the same.

Clarifications

  • The input board will always be from a 4x4 board.
  • You can take in the board as an array of the 16 values, as 16 different inputs or even a 2D array if that somehow helps you.
  • The input numbers will always be zero or 2 to the power of a positive integer.
  • You can discard any errors due to floating point operations (but theoretically the program must implement a correct algorithm).
  • This is , the shortest code wins!

Test-cases

[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -> 0
[2,4,2,4,4,2,4,2,2,4,2,4,4,2,4,2] -> 28.8
[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4] -> 57.6
[0,0,0,4,0,0,0,8,0,0,0,16,2,2,0,2048] -> 20340.4
[2,16,2048,4096,4,32,1024,8192,8,64,512,16384,16,128,256,32768] -> 845465.2
[8,8,4,4,0,0,0,0,0,0,2,2,2048,65536] -> 996799.2
\$\endgroup\$
6
  • \$\begingroup\$ @LuisMendo 90% of the time a given 4 gets made from combining two 2 pieces, while 10% of the time they appear as one and give no score \$\endgroup\$
    – dzaima
    Aug 31, 2017 at 16:28
  • \$\begingroup\$ @LuisMendo A 4 piece isn't always made from combining two 2's, as 10% of the time when a piece spawns in after a move, it starts as a 4 \$\endgroup\$
    – dzaima
    Aug 31, 2017 at 16:33
  • \$\begingroup\$ Out of 9 spawned 2's one can only create 4.5 4's, not 9. Shouldn't the average score of a 4 piece be 9/11 * 4 = 3.2727... ? \$\endgroup\$
    – ovs
    Aug 31, 2017 at 17:18
  • \$\begingroup\$ @ovs Even if my math is wrong, the challenge will stay this way. Trying to figure what you mean (and now even why I thought my method was correct) \$\endgroup\$
    – dzaima
    Aug 31, 2017 at 17:25
  • \$\begingroup\$ if 20 new pieces spawn, 2 4's and 18 2's. We can create additional 9 4's by merging the 2's. We now have 11 4's with a total score of 36 and an average score of 36/11 = 3.2727... \$\endgroup\$
    – ovs
    Aug 31, 2017 at 17:32

4 Answers 4

4
\$\begingroup\$

Python 3, 51 48 bytes

-3 bytes thanks to Mr. Xcoder!

lambda b:sum(n*max(0,len(bin(n))-4.1)for n in b)

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 48 bytes. n.bit_length() means len(bin(n))-2, which we can compress into len(bin(n))-4.1 \$\endgroup\$
    – Mr. Xcoder
    Aug 31, 2017 at 16:43
  • \$\begingroup\$ @Mr.Xcoder Nice. I was sure there was some easier way to do number of bits but I blanked for some reason. \$\endgroup\$
    – notjagan
    Aug 31, 2017 at 16:44
1
\$\begingroup\$

C# (.NET Core), 101 100 bytes

n=>{double k=0,l=0;for(int i=0,j;i<n.Length;l+=k,++i)for(j=4;j<=n[i];j*=2)k=j>4?k*2+j:3.6;return l;}

Try it online!

Lambda function. Takes in an array for the board, and returns a double for the score

\$\endgroup\$
1
\$\begingroup\$

APL (Dyalog Extended), 18 bytes

+/{⍵×0⌈2.1-⍨≢⊤⍵}¨⎕

Try it online! or Verify all test cases

Full program submission.

Port of the Python answer.

Explanation

+/{⍵×0⌈2.1-⍨≢⊤⍵}¨⎕
                ¨⎕ to each element of the input:
              ⊤⍵   convert to base 2 digits
       2.1-⍨≢      length - 2.1
     0⌈            maximum with 0
   ⍵×              times the element
+/                 sum the resulting array 
\$\endgroup\$
1
\$\begingroup\$

JavaScript (V8), 58 bytes

b=>b.reduce((a,n)=>a+(z=x=>x>4?z(x/2)*2+x:x-4?0:3.6)(n),0)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.