Mid-Autumn Festival gambling game

JavaScript (ES6), 88 bytes

a=>a.map(o=n=>[x=o[n]=-~o[n],6,,,21,9,8^o[1]][a=x<a?a:x])[5]|[,1,4,5,o[1]&2|8,2,4][o[4]]

Try it online! or Test all possible rolls!

Outputs an integer according to the following mapping:

 Rank | Output       Rank | Output
------+--------     ------+--------
   0  |  31            7  |   7
   1  |  12            8  |   5
   2  |  14            9  |  21
   3  |   8           10  |   4
   4  |  11           11  |   1
   5  |   9           12  |   0
   6  |  29

How?

Method

The output is computed by performing a bitwise OR between:

  • a bitmask based on \$F\$: the number of 4's
  • a bitmask based on \$M\$: the maximum number of occurrences of the same dice

Exceptions:

  • When \$F=4\$: we use a special bitmask \$4b\$ when the two other dice are 1's, or a default bitmask \$4a\$ otherwise.
  • When \$M=6\$: we use a special bitmask \$6b\$ when we have a six-of-a-kind of 1's, or a default bitmask \$6a\$ otherwise.

Table

Valid combinations of \$F\$ and \$M\$ are highlighted in bold and blue in the following table.

$$\begin{array}{c|c|cccccccc} &F&0&1&2&3&4a&4b&5&6\\ \hline M&\text{OR}&0&1&4&5&8&10&2&4\\ \hline 1&6&\color{grey}{6}&\color{blue}{\textbf{7}}&\color{grey}{6}&\color{grey}{7}&\color{grey}{14}&\color{grey}{14}&\color{grey}{6}&\color{grey}{6}\\ 2&0&\color{blue}{\textbf{0}}&\color{blue}{\textbf{1}}&\color{blue}{\textbf{4}}&\color{grey}{5}&\color{grey}{8}&\color{grey}{10}&\color{grey}{2}&\color{grey}{4}\\ 3&0&\color{blue}{\textbf{0}}&\color{blue}{\textbf{1}}&\color{blue}{\textbf{4}}&\color{blue}{\textbf{5}}&\color{grey}{8}&\color{grey}{10}&\color{grey}{2}&\color{grey}{4}\\ 4&21&\color{blue}{\textbf{21}}&\color{blue}{\textbf{21}}&\color{blue}{\textbf{21}}&\color{grey}{21}&\color{blue}{\textbf{29}}&\color{blue}{\textbf{31}}&\color{grey}{23}&\color{grey}{21}\\ 5&9&\color{blue}{\textbf{9}}&\color{blue}{\textbf{9}}&\color{grey}{13}&\color{grey}{13}&\color{grey}{9}&\color{grey}{11}&\color{blue}{\textbf{11}}&\color{grey}{13}\\ 6a&8&\color{blue}{\textbf{8}}&\color{grey}{9}&\color{grey}{12}&\color{grey}{13}&\color{grey}{8}&\color{grey}{10}&\color{grey}{10}&\color{blue}{\textbf{12}}\\ 6b&14&\color{blue}{\textbf{14}}&\color{grey}{15}&\color{grey}{14}&\color{grey}{15}&\color{grey}{14}&\color{grey}{14}&\color{grey}{14}&\color{grey}{14}\\ \end{array}$$

All other combinations (in gray) can't possibly happen. For instance, if we have three 4's, we must have \$M\ge3\$. But because there are only 3 other remaining dice in such a roll, we also have \$M\le3\$. So, there's only one possible value of \$M\$ for \$F=3\$.

Example

If we have a straight, each dice appears exactly once. So we have \$M=1\$ and \$F=1\$. Using the bitmasks described in the above table, this leads to:

$$6 \text{ OR } 1 = 7$$

There is another \$7\$ in the table, but it's invalid. Therefore, a straight is uniquely identified by \$7\$.

Commented

a =>                   // a[] = input array, reused as an integer to keep track of the
  a.map(               //       maximum number of occurrences of the same dice (M)
    o =                // o = object used to count the number of occurrences of each dice
    n =>               // for each dice n in a[]:
    [                  //   this is the lookup array for M-bitmasks:
      x =              //     x = o[n] = number of occurrences of the current dice
        o[n] = -~o[n], //     increment o[n] (we can't have M = 0, so this slot is not used)
      6,               //     M = 1 -> bitmask = 6
      ,                //     M = 2 -> bitmask = 0
      ,                //     M = 3 -> bitmask = 0
      21,              //     M = 4 -> bitmask = 21
      9,               //     M = 5 -> bitmask = 9
      8 ^ o[1]         //     M = 6 -> bitmask = 14 for six 1's, or 8 otherwise
    ][a =              //   take the entry corresponding to M (stored in a)
        x < a ? a : x] //   update a to max(a, x)
  )[5]                 // end of map(); keep the last value
  |                    // do a bitwise OR with the second bitmask
  [                    // this is the lookup array for F-bitmasks:
    ,                  //   F = 0 -> bitmask = 0
    1,                 //   F = 1 -> bitmask = 1
    4,                 //   F = 2 -> bitmask = 4
    5,                 //   F = 3 -> bitmask = 5
    o[1] & 2 | 8,      //   F = 4 -> bitmask = 10 if we also have two 1's, 8 otherwise
    2,                 //   F = 5 -> bitmask = 2
    4                  //   F = 6 -> bitmask = 4
  ][o[4]]              // take the entry corresponding to F (the number of 4's)

R, 100 bytes

Encode the score as a bunch of indexed conditionals. Simpler than my first stringy-regex approach.

Edit- fixed bug and now rank all rolls.

function(d,s=sum(d<2))min(2[s>5],c(11,10,8,6-6*!s-2,4,1)[sum(d==4)],c(7,12,12,9,5,3)[max(table(d))])

Try it online!


JavaScript (Node.js), 169 bytes

a=>-~"114444|123456".search(w=a.sort().join``,[l,t]=/(.)\1{3,}/.exec(w)||[0],l=l.length)||(l>5?3-"14".search(t):l>3?4+(5.5-l)*(t-4?4:2):[,13,12,11,9][w.split`4`.length])

Try it online!

Returns 1..13

Tags:

Code Golf

Game