assert 300 isScore bowlingScores 12#10
This needs an implementation:
bowlingScores=: 3 ]\ ]
Easy enough, and that works.
assert 190 isScore bowlingScores 21$9 1
This fails with my current definition for bowlingScores. The problem is that my result has too many rows in it. If I had a way of eliminating them, I would have the right result:
+/@,(#~ 9={."1) bowlingScores 21$9 1
190
But I don't want to use this technique because it is too closely tied to the example score. What I really need is a way of ignoring potential frames immediately after a frame that did not begin with a 10.
validFrames=:3 :0
valid=. 0 NB. first potential frame is always a valid frame
while. (#y) > {: valid do.
valid=. valid, ({:valid) + 1 + 10 ~: {. ({:valid) { y
end.
(i.#y) e. valid
)
That implementation seems overly complicated, but it works:
+/, (#~ validFrames) 3 ]\ 21$9 1
190
Some issues here:
- I am repeatedly referring to the last element of valid.
- Each element of valid depends on all of the previous elements (and its first element is always 0).
- The last element of valid is not really valid (because it's an index off the end of the array), but that does not actually matter for well-formed games, since no valid index will ever match it.
- I have written this code so that it can work on a flat list of ball scores or an array of them.
- If a game goes too long, this code will not ignore irrelevant trailing ball scores.
For an inductive approach, the initial value is always 0. So I need a function that, given one value will give me the next value.
In other words, I need a function that adds 1 to an index if the value at that index is 10, and which otherwise adds 2 to that index.
But, I also need my function to not have problems from indexing off the end of my scores.
For example, if my potential frames are my left argument:
F=: ] + 1 + 10 > {.@{~
(19 3$9 1) F^:(i.10) 0
0 2 4 6 8 10 12 14 16 18
This leaves me with my new definition:
bowlingScores=: ({~ F^:(i.10)&0)@(3 ]\ ])
That satisfies both of my assertions so far, but lunch time is over so I need to put the rest of this off until later.
For now, here are my collected definitions and assertions:
isScore=: -:&(+/@,) , (10 3 >: $@]) , 2 -: #@$@]
F=: ] + 1 + 10 > {.@{~
bowlingScores=: ({~ F^:(i.10)&0)@(3 ]\ ])
assert 300 isScore bowlingScores 12#10
assert 190 isScore bowlingScores 21$9 1
No comments:
Post a Comment