Score a game of Bowling

GolfScript, 50 41 characters

~0]-1%~0{\.9>{+1$3$}{@+.9>3$*}if++}10*p];

Another attempt in GolfScript (run it online).

An explanation of the code follows. The solution utilises the stack nature of the problem (consume rolls one after another) but therefore the input has to be reversed.

~0          # Take the input and evaluate to single numbers on the stack. Add zero.
]-1%~       # Reverse the stack (make array, reverse array, dump array)

0           # Start with a sum of zero
{           # Perform this block 10 times (once for each round)
  \         #   Take the next roll
  .9>{      #   If it is a strike
    +       #     Add the value of the roll to the sum
    1$3$    #     and duplicate top two members of the stack (i.e. next two rolls).
  }{        #   ... else ...
    @+      #     Take the next roll and add with first roll in round.
    .9>     #     Does this sum show a spare?
    3$*     #     Get next roll (potential bonus) and multiply with yes/no.
            #     Since we pushed an additional 0 in the beginning 
            #     there is a spare roll even for the last round.
  }if       #   endif
  ++        #   Add top three stack entries together
            #   (i.e. sum+2 bonus rolls for strike, sum+rolls+bonus else)
}10*        # Loop ten times

p];         # Sum is top of stack. Print sum and discard any leftover rolls.

Previous version:

~].1>.1>]zip{((.10<{@(0=@+@1>1$9><}*@}10*;]{+}.@**

Python, 116 110 105 103 100 99 characters

z=map(int,raw_input().split())
s=0
exec('s+=sum(z[:2+(z[0]+z[1]>9)]);z=z[2-(z[0]>9):];'*10)

Spending 30 characters on input is irksome. Suggestions welcome.

Much thanks to Howard for improvements.


R, 101 bytes

I am not sure why this challenge was bumped, but I like it, so I'll late answer anyways.

f=function(x,s=0,c=10)`if`(c&length(x),f(x[-(0:(x[1]!=10)+1)],sum(x[1:(2+(sum(x[1:2])>9))])+s,c-1),s)

Try it online!

Ungolfed:

f <- function(throws, score = 0, count = 10){
  if(count != 0 & length(throws) != 0){
    IsStrike <- throws[1] == 10
    IsStrikeOrSpare <- sum(throws[1:2]) >= 10
    f(throws[-c(1, 2 * !IsStrike)],
      score + sum(throws[c(1:(2 + IsStrikeOrSpare))]),
      count - 1)
  } else {
    return(score)
  }
}

Recursive function. Takes x as input, which holds the scores. Initialises the scores and counts the amount of rounds thrown.

The if statement checks if 10 rounds are thrown, or if x is empty. If that is the case, the score is returned. Else the function will call itself as follows:

It removes the throws from x, by checking if it is a strike or not. If so, the first entry is removed, else the first two. (S=x[1]!=10) checks for strikes. We remove (-) index 0:S, where S is 1 if it is a strike, and 0 if not. And then we add one: -(0:(x[1]!=10)+1). We pass the shortened x to the next call.

As for the score, this is found by taking x[1:2] if it is a regular turn, and x[1:3] if it is a strike or a spare. We check if sum(x[1:2]) is bigger or equal than 10. If it is a strike, obviously this is the case. If it is a spare, then this works as well. So if this is TRUE, we add x[3] to the sum. This is then added to s.