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