I can't go bowling without recalling my discovery in beginning programming when I coded a scoring algorithm with a simple loop by looking ahead at the next frame rather than carrying incomplete bonuses forward and then back-patching results as is done when scoring in realtime.
Specifically, when scoring a strike, one applies the bonus of adding in the sum of the next two balls thrown. These could be thrown in the next frame, or the next two frames. This means bonuses can pile up creating a dynamic representation problem for the programmer.
I remember struggling with this logic when I realized I could just look ahead to the future frames while scoring the current frame. I checked the programming assignment. Nothing was said about scoring in realtime. The assignment called for reading the pins for each ball into an array. There it was, all the information for all time.
score = (j) -> pins[j][0] + (pins[j][1] or 0) bonus = (j) -> if pins[j][0] == 10 pins[j+1][0] + (pins[j+1][1] or pins[j+2][0]) else if score(j) == 10 pins[j+1][0] else 0
See Bowling Score Spiked.