12
\$\begingroup\$

For each of the 13 rows of a Yahtzee scoresheet you are given (from stdin) a space separated list of 5 numbers (dice). Your task is to calculate the score for each line and output the Grand Total of the game.

Example

Input and how to interpret it:

Input       Box              Score
6 1 4 1 3   Aces              2
3 2 2 1 2   Twos              6
6 3 2 3 3   Threes            9
4 2 3 6 5   Fours             4  
6 3 5 5 1   Fives            10
1 5 6 5 6   Sixes            12
            Bonus             -
4 2 4 4 1   3 of a kind      15
2 2 3 2 4   4 of a kind       -
3 2 2 2 3   Full house       25  
1 3 1 6 1   Small straight    -
2 5 4 6 3   Large straight   40
2 2 2 2 2   Yahtzee          50
5 5 4 5 2   Chance           21
            Grand Total     194

We will disregard the Yahtzee Bonus and Joker rules, and only sum up the scores from the Upper and Lower Section and the Bonus in the Upper Section. If in doubt, refer to these rules.

May the shortest code win!

\$\endgroup\$
7
  • \$\begingroup\$ For the benefit of those who don't speak Norwegian, could you list the scoring rules you want people to implement directly in the question? \$\endgroup\$ Sep 26, 2012 at 17:08
  • \$\begingroup\$ Heh heh ;) The rules are the same, it's only some of the blocks that have changed positions, and the addition of 1 and 2 pair. The first code-block is the rough translation (without "Sum" and "Bonus") so just refer to that one. The Norwegian link was just to justify the order of the blocks for people who may be used to other setups. I think the rules are clear, and that the "pair" blocks are pretty self-explanatory. The rest of the rules should be explained on the English wiki link I provided. \$\endgroup\$
    – daniero
    Sep 26, 2012 at 17:18
  • \$\begingroup\$ Oh, I just realized, the rules are different. I will use the official, "international" rules then: yahtzeerules.com/yahtzee-scoring.htm (I like the Norwegian ones better, it has more variations in possible scores) -- I'll change the question in a moment. \$\endgroup\$
    – daniero
    Sep 26, 2012 at 17:39
  • \$\begingroup\$ You are actually going to match the input cards to the scoring line? Shouldn't we have to figure out which line is most appropriate for any given hand? \$\endgroup\$
    – DavidC
    Sep 27, 2012 at 2:51
  • 1
    \$\begingroup\$ @Matt Based after skimming through some top results from a certain search engine, I'll say 'yes'. \$\endgroup\$
    – daniero
    Sep 27, 2012 at 13:53

6 Answers 6

5
\$\begingroup\$

R - 264

S=sum;
P=prod;
T=function(i)table(x[i,]);
Z=function(i,...)any(sapply(list(...),function(y)all(y%in%x[i,])))
S((x[1:6,]==(R=row(x[1:6,])))*R)+ # Upper section
S(x[7,])*any(T(7)>2)+             # 3 of a kind
S(x[8,])*any(T(8)>3)+             # 4 of a kind
25*(P(T(9))%in%5:6)+              # Full house
30*Z(10,1:4,2:5,3:6)+             # Small straight
40*Z(11,1:5,2:6)+                 # Large straight
50*(P(T(12))==5)+                 # Yahtzee
S(x[13,])                         # Chance

(264 characters when excluding the comments)

With the input

x <- as.matrix(read.table("http://pastebin.com/raw.php?i=ZRMC9B4x"))

Output

[1] 194
\$\endgroup\$
4
  • \$\begingroup\$ Nice to see that someone manages to get the right output :D I'll update the example. \$\endgroup\$
    – daniero
    Sep 27, 2012 at 9:58
  • \$\begingroup\$ I think your program incorrectly handles full house. I tested dice 2 2 2 2 2 and I believe your program treats that as a full house and awards the 25 points. \$\endgroup\$
    – Matt
    Sep 27, 2012 at 12:21
  • \$\begingroup\$ I think there is also a problem with the large and small straights. If all dice are the same (I again tested 2 2 2 2 2) I get a result of numeric(0) instead of a score. \$\endgroup\$
    – Matt
    Sep 27, 2012 at 12:26
  • \$\begingroup\$ @Matt, where I come from (my rules or everyone's?) you can score a yahtzee (e.g. 2 2 2 2 2) under "Full house". I think you are correct about the straights, thanks; I will update my code with a shorter version I thought about. \$\endgroup\$
    – flodel
    Sep 27, 2012 at 12:54
4
\$\begingroup\$

APL (124)

S←{⍺∊+⌿⍵∘.=⍵}⋄+/(+/⎕)(50×∧/,A∘.=A←⎕)(+/10×{⍵×∨/(⍳⍵)⍷1+A-⊃A←A[⍋A←⎕]}¨N)(25×∧/S∘⎕¨2 3)(+/{(+/A)×⍵S⊢A←⎕}¨N←3 4)(+/{+/⍵×⍵=⎕}¨⍳6)
\$\endgroup\$
2
  • 4
    \$\begingroup\$ I swear this looks identical to something I read on the side of an alien spaceship. \$\endgroup\$ Oct 11, 2012 at 1:45
  • \$\begingroup\$ I have no idea if this program works or not, but surely it's the shortest :D \$\endgroup\$
    – daniero
    Oct 26, 2012 at 15:00
4
\$\begingroup\$

Python 364

S=sum;R=range;D=[map(int,raw_input().split())for i in R(13)];s=S(x for i in R(6)for x in D[i]if x==i+1)
for i in R(2):d=D[6+i];s+=[0,S(d)][max(map(d.count,d))>2+i];d=sorted(set(D[9+i]));s+=[0,30+i*10]['1, 1, 1'+', 1'*i in`[d[x+1]-d[x]for x in R(len(d)-1)]`]
e=D[8];a=map(e.count,e);d=D[11];print s+S(D[12])+[0,50][d.count(d[0])==5]+[0,25][2in a and 3in a or 5in a]

As requested, input is on stdin:

$ yScore.py < dice.txt
194

If the data could be preloaded into a list, as some other solutions have done, I could remove 62 characters to get to 302.

\$\endgroup\$
3
\$\begingroup\$

Mathematica 359

y = IntegerDigits@ImportString[x, "Table"][[1]];
l = Length; g = Gather; r = Range; b = SortBy; h = l@b[g[y[[#]]], l][[-1]] &;
Tr@Flatten@{# Count[y[[#]], #] & /@ r@6, If[h@7 == 3, 15, 0], 
If[h@8 == 4, 20, 0], If[(l /@ b[g[y[[9]]], l]) == {2, 3}, 25, 0], 
If[MatchQ[Sort@y[[10]], {___, n_, m_, o_, q_, ___} /; m == n + 1 && o == m + 1 && q == o + 1], 30, 0], 
If[Sort[y[[11]]] == r[y[[11, 1]], y[[11, 1]] + 4], 40, 0], 
If[l@g[y[[12]]] == 1, 50, 0], y[[13]]}

There must be a more efficient way to check for the short straight.

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

GolfScript 180

n/{~]}%6,{)`['{''=},,''*']*}%[{.{+}*\{..|{'{'\'=},,'++1$\~}%$\;}:g~)\;2>*}{.{+}*\g)\;3>*}{g[2 3]=25*}{$:§;3,{).4+,\>§-}%1?)!!30*}{.$(\;.5+,\>\-!40*}{g)\;5=50*}{{+}*}]+]zip{~~}%{+}*

You can test the program here

Annotated program:

n/                          # split input by newline
{~]}%                       # parse an int array from each line

6,{)`['{''=},,''*']*}%      # create {X=},,X* code blocks, 
                            # where X goes from 1 to 6 
                            # (needed for processing the first 
                            # half of the board)

[       # create an array of code blocks, for scoring:

        # three of a kind:
    {.{+}*\{..|{'{'\'=},,'++1$\~}%$\;}:g~)\;2>*}

        # four of a kind:
    {.{+}*\g)\;3>*}

        # full house:
    {g[2 3]=25*}

        # small straight:
    {$:§;3,{).4+,\>§-!}%1?)!!30*}

        # straight: 
    {.$(\;.5+,\>\-!40*}

        # yahtzee:
    {g)\;5=50*}

        #chance:
    {{+}*}
]+              # concatenate the 1-6 code block array with this one

]zip            # distribute each line in the input 
                # to the corresponding scoring rule (code block)

{~~}%           # evaluate each input/code pair
                # and get an array with score for each hand

{+}*            # sum up the partial scores.
\$\endgroup\$
1
\$\begingroup\$

Perl 527 characters

while(<>){$l++;$q=$c=0;$q=1if(($_=~/1/&&$_=~/2/&&$_=~/3/&&$_=~/4/)||($_=~/5/&&$_=~/2/&&$_=~/3/&&$_=~/4/)||($_=~/5/&&$_=~/6/&&$_=~/3/&&$_=~/4/));@a=split//;for(@a){$c++if/$l/;}$s+=$l*($c)if$l<7;$s+=35if$s>=63&&$l==6;for$i(1...6){$t=0;$f+=$c if($l==9&&($c==2||$c==3));$c=0if!($l==11&&$c>1);for(@a){$t+=$_;$c++if/$i/;}$s+=$t if($c>=3&&$l==7);$s+=$t if($c>=4&&$l==8);$s+=50if($c==5&&$l==12);$s+=$t if($l==13&&$i==6);}$s+=25if($f==5&&$l==9);$s+=30if($q==1&&$l==10);$s+=40if($c<2&&($t==15||$t==20)&&$l==11);exit(print $s)if($l==13);}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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