From d21318ff56c5fab73ba8d224b63f8c8f6798958f Mon Sep 17 00:00:00 2001 From: John Sutherland Date: Mon, 4 Aug 2014 23:20:46 +0100 Subject: [PATCH] Initial version of Bowling Game Kata --- README.md | 6 ++++++ solution.clj | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 README.md create mode 100644 solution.clj diff --git a/README.md b/README.md new file mode 100644 index 0000000..1ec3c50 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Solution to the Bowling Game Kata + +An initial stab at the [Bowling Game Kata][bsk] in Clojure. + + +[bsk]: http://content.codersdojo.org/code-kata-catalogue/bowling-game/ diff --git a/solution.clj b/solution.clj new file mode 100644 index 0000000..25669ce --- /dev/null +++ b/solution.clj @@ -0,0 +1,50 @@ +(ns solution + (:use clojure.test)) + + +(defn split-into-frames + "Splits a set of rolls into frames." + [rolls] + (cond (empty? rolls) [] + (= (first rolls) 10) (cons '(10 0) (split-into-frames (rest rolls))) + :else (cons (take 2 rolls) (split-into-frames (drop 2 rolls))))) + +(defn is-strike + "true if the first item in rolls is a strike" + [rolls] + (= 10 (first rolls))) + +(defn is-spare + "true if the first two items in rolls make a spare" + [rolls] + (= 10 (+ (first rolls) (second rolls)))) + +(defn frame-score + "Calculates a frame's score" + [rolls] + (cond (is-strike rolls) (apply + (take 4 rolls)) + (is-spare rolls) (apply + (take 3 rolls)) + :else (apply + (take 2 rolls)))) + +(defn score + "Scores a collection of rolls" + [rolls] + (loop [frame-rolls (flatten (split-into-frames rolls)) + frames 0 + score 0] + (if (or + (<= (count frame-rolls) 1) + (= frames 10)) + score + (recur (drop 2 frame-rolls) (inc frames) (+ score (frame-score frame-rolls)))))) + + +(deftest score-from-example + (is (= 133 (score [1 4 4 5 6 4 5 5 10 0 1 7 3 6 4 10 2 8 6]))) + (is (= 17 (score [0 10 3 1]))) + (is (= 18 (score [10 3 1]))) + (is (= 45 (score [10 5 5 6 3]))) + (is (= 0 (score [])))) + + +(run-tests)