I think you guys are really overthinking this problem.  Because
Clojure inherits Java's stack limitations, we tend to get hung up on
converting elegant recursive code into loop/recur/accumulator
structures.  But here, we have a problem that we know isn't going to
blow the stack, so just think recursively and you end up with a
solution that is short and easy to understand:

(use 'clojure.contrib.test-is)

; A game is a sequence of numbers, representing how many pins were
knocked down for that roll

(defn sum [s] (reduce + s))
(defn score [game]
  (cond
    (< (count game) 3)      (sum game),

    (= (first game) 10)     (+ (sum (take 3 game))
                               (score (drop 1 game))),

    (= (sum (take 2 game)) 10)
    (+ (sum (take 3 game)) (score (drop 2 game))),

    :else (+ (sum (take 2 game)) (score (drop 2 game)))))

(deftest sample-games
  (is (score [1 0 1 10 2 2 10 3 3 10 1 10 3 10 10 1 2]) 108)
  (is (score [1 0 1 10 2 2 10 3 3 10 1 10 3 10 1 10 10 8 0]) 121)
  (is (score [1 0 1 10 2 2 10 3 3 10 1 10 3 10 1 10 8 10 9]) 120))


;;;;;;;;;;;;
You can improve efficiency by enforcing an input of vectors and using
subvec, or you can keep the generality of sequences but change the
first test to something like (= (count (take game 3)) 3), but really,
why bother doing *anything* at the expense of clarity for a problem
where the inputs are so small that efficiency is a non-issue.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to