Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

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!

share|improve this question
    
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? –  Peter Taylor Sep 26 '12 at 17:08
    
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. –  daniero Sep 26 '12 at 17:18
    
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. –  daniero Sep 26 '12 at 17:39
    
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? –  David Carraher Sep 27 '12 at 2:51
1  
@Matt Based after skimming through some top results from a certain search engine, I'll say 'yes'. –  daniero Sep 27 '12 at 13:53
show 2 more comments

6 Answers 6

up vote 3 down vote accepted

APL (124)

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

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
share|improve this answer
    
Nice to see that someone manages to get the right output :D I'll update the example. –  daniero Sep 27 '12 at 9:58
    
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. –  Matt Sep 27 '12 at 12:21
    
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. –  Matt Sep 27 '12 at 12:26
    
@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. –  flodel Sep 27 '12 at 12:54
add comment

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.

share|improve this answer
add comment

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.

share|improve this answer
add comment

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.
share|improve this answer
add comment

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);}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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