# Yahtzee

Yahtzee

The game of Yahtzee involves five dice, which are thrown in 13 rounds. A score card contains 13 categories. Each round may be scored in a category of the player's choosing, but each category may be scored only once in the game. The 13 categories are scored as follows:

ones - sum of all ones thrown
twos - sum of all twos thrown
threes - sum of all threes thrown
fours - sum of all fours thrown
fives - sum of all fives thrown
sixes - sum of all sixes thrown

chance - sum of all dice

three of a kind - sum of all dice, provided at least three have same value
four of a kind - sum of all dice, provided at least four have same value
five of a kind - 50 points, provided all five dice have same value
short straight - 25 points, provided four of the dice form a sequence (that is, 1,2,3,4 or 2,3,4,5 or 3,4,5,6)
long straight - 35 points, provided all dice form a sequence (1,2,3,4,5 or 2,3,4,5,6)
full house - 40 points, provided three of the dice are equal and the other two dice are also equal. (for example, 2,2,5,5,5)
Each of the last six categories may be scored as 0 if the criteria are not met.

The score for the game is the sum of all 13 categories plus a bonus of 35 points if the sum of the first six categories is 63 or greater.

Your job is to compute the best possible score for a sequence of rounds.

Each line of input contains five integers between 1 and 6, indicating the values of the five dice thrown in each round. There are 13 such lines for each game, and there may be any number of games in the input data.

Your output should consist of a single line for each game containing 15 numbers: the score in each category (in the order given), the bonus score (0 or 35), and the total score. If there is more than categorization that yields the same total score, any one will do.

``````1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 1 1 1 1
6 6 6 6 6
6 6 6 1 1
1 1 1 2 2
1 1 1 2 3
1 2 3 4 5
1 2 3 4 6
6 1 2 6 6
1 4 5 5 5
5 5 5 5 6
4 4 4 5 6
3 1 3 6 3
2 2 2 4 6

``````

``````1 2 3 4 5 0 15 0 0 0 25 35 0 0 90
3 6 9 12 15 30 21 20 26 50 25 35 40 35 327

``````

``````#include <stdio.h>

int round[5];
int best[8192][64];
int predk[8192][64], predm[8192][64];
int cat[13];
int nbits[8192];

int cmp(int *a, int *b){
if (*a<*b) return -1;
if (*a>*b) return +1;
return 0;
}

main(){
for (k=0;k<8192;k++){
for (m=0;m<13;m++){
mask += (k & (1<<m)) != 0;
}
}
for (;;){
for (i=0;i<8192;i++) for (j=0;j<64;j++) best[i][j] = -99999;
best[0][0] = 0;
for (i=0;i<13;i++){
if (5 != scanf("%d%d%d%d%d",round,round+1,round+2,round+3,round+4)) return 0;
qsort(round,5,sizeof(int),cmp);
for (j=0;j<13;j++){
int score = 0, topscore = 0;
switch (j) {
case 0: /* ones */
case 1: /* twos */
case 2: /* threes */
case 3: /* fours */
case 4: /* fives */
case 5: /* sixes */
for (k=0;k<5;k++) if (round[k] == j+1) score += j+1;
topscore = score;
break;
case 6: /* chance*/
for (k=0;k<5;k++) score += round[k];
break;
case 7: /* 3 kind*/
if (round[0] == round[2] || round[1] == round[3] ||
round[2] == round[4])
for (k=0;k<5;k++) score += round[k];
break;
case 8: /* 4 kind*/
if (round[0] == round[3] ||
round[1] == round[4])
for (k=0;k<5;k++) score += round[k];
break;
case 9: /* 5 kind*/
if (round[0] == round[4])
score = 50;
break;
case 10: /* short */
if (round[1]==round[2]-1&&round[2]==round[3]-1
&&(round[0]==round[1]-1||round[3]==round[4]-1))
score = 25;
break;
case 11: /* long */
if (round[1]==round[2]-1&&round[2]==round[3]-1
&&round[0]==round[1]-1&&round[3]==round[4]-1)
score = 35;
break;
case 12: /* house */
if((round[0]==round[1]&&round[2]==round[4])
||(round[0]==round[2]&&round[3]==round[4]))
score = 40;
break;
}
for (k=0;k<8192;k++){
if (nbits[k] != i) continue;
for (m=0;m<64;m++){
register newscore = best[k][m] + score;
register newtop = m + topscore;
if (newtop > 63) newtop = 63;
}
}
}
}
}
{
int bestk=8191,bestm=63,bonus=35;
j = bonus + best[8191][63];
for (i=0;i<63;i++) if (best[8191][i] > j) {
j = best[8191][i];
bestm = i;
bonus = 0;
}
while (bestk) {
int x = bestk ^ predk[bestk][bestm];
for (i=0;x>>=1;i++){}
cat[i] = best[bestk][bestm] -
best[predk[bestk][bestm]][predm[bestk][bestm]];
x = predk[bestk][bestm];
bestm = predm[bestk][bestm];
bestk = x;
}
for (i=0;i<13;i++) printf("%d ",cat[i]);
printf("%d %d\n",bonus,j);
}
}
}
``````

``````#include <stdio.h>

int round[5];
int best[8192][64];
int predk[8192][64], predm[8192][64];
int cat[13];
int nbits[8192];

int cmp(int *a, int *b){
if (*a<*b) return -1;
if (*a>*b) return +1;
return 0;
}

main(){
for (k=0;k<8192;k++){
for (m=0;m<13;m++){
mask += (k & (1<<m)) != 0;
}
}
for (;;){
for (i=0;i<8192;i++) for (j=0;j<64;j++) best[i][j] = -99999;
best[0][0] = 0;
for (i=0;i<13;i++){
if (5 != scanf("%d%d%d%d%d",round,round+1,round+2,round+3,round+4)) return 0;
qsort(round,5,sizeof(int),cmp);
for (j=0;j<13;j++){
int score = 0, topscore = 0;
switch (j) {
case 0: /* ones */
case 1: /* twos */
case 2: /* threes */
case 3: /* fours */
case 4: /* fives */
case 5: /* sixes */
for (k=0;k<5;k++) if (round[k] == j+1) score += j+1;
topscore = score;
break;
case 6: /* chance*/
for (k=0;k<5;k++) score += round[k];
break;
case 7: /* 3 kind*/
if (round[0] == round[2] || round[1] == round[3] ||
round[2] == round[4])
for (k=0;k<5;k++) score += round[k];
break;
case 8: /* 4 kind*/
if (round[0] == round[3] ||
round[1] == round[4])
for (k=0;k<5;k++) score += round[k];
break;
case 9: /* 5 kind*/
if (round[0] == round[4])
score = 50;
break;
case 10: /* short */
if (round[1]==round[2]-1&&round[2]==round[3]-1
&&(round[0]==round[1]-1||round[3]==round[4]-1))
score = 25;
break;
case 11: /* long */
if (round[1]==round[2]-1&&round[2]==round[3]-1
&&round[0]==round[1]-1&&round[3]==round[4]-1)
score = 35;
break;
case 12: /* house */
if((round[0]==round[1]&&round[2]==round[4])
||(round[0]==round[2]&&round[3]==round[4]))
score = 40;
break;
}
for (k=0;k<8192;k++){
if (nbits[k] != i) continue;
for (m=0;m<64;m++){
register newscore = best[k][m] + score;
register newtop = m + topscore;
if (newtop > 63) newtop = 63;
}
}
}
}
}
{
int bestk=8191,bestm=63,bonus=35;
j = bonus + best[8191][63];
for (i=0;i<63;i++) if (best[8191][i] > j) {
j = best[8191][i];
bestm = i;
bonus = 0;
}
while (bestk) {
int x = bestk ^ predk[bestk][bestm];
for (i=0;x>>=1;i++){}
cat[i] = best[bestk][bestm] -
best[predk[bestk][bestm]][predm[bestk][bestm]];
x = predk[bestk][bestm];
bestm = predm[bestk][bestm];
bestk = x;
}
for (i=0;i<13;i++) printf("%d ",cat[i]);
printf("%d %d\n",bonus,j);
}
}
}
``````