Skip to content

Instantly share code, notes, and snippets.

@keelerm84
Created February 16, 2014 17:30
Show Gist options
  • Save keelerm84/9037640 to your computer and use it in GitHub Desktop.
Save keelerm84/9037640 to your computer and use it in GitHub Desktop.
Clojure implementation of the bowling kata
(ns bowling.core)
(defn spare? [rolls]
(= 10 (reduce + (take 2 rolls))))
(defn strike? [rolls]
(= 10 (first rolls)))
(defn take-how-many [rolls]
(if (or (spare? rolls) (strike? rolls)) 3 2))
(defn drop-how-many [rolls]
(if (strike? rolls) 1 2))
(defn make-frames [rolls]
(let [must-take (take-how-many rolls)
must-drop (drop-how-many rolls)]
(lazy-seq
(cons
(take must-take rolls)
(make-frames (drop must-drop rolls))))))
(defn make-game [rolls]
(take 10 (make-frames rolls)))
(defn frame-score [frame]
(reduce + frame))
(defn game-score [rolls]
(reduce + (map frame-score (make-game rolls))))
(ns bowling.core-test
(:use clojure.test
bowling.core))
(deftest spare?-test
(testing "We know what a spare is"
(is (= true (spare? [1 9])))
(is (= false (spare? [1 1])))
(is (= false (spare? [10 1])))))
(deftest strike?-test
(testing "We know what a strike is"
(is (= true (strike? [10 1 9])))
(is (= false (strike? [1 9 10])))))
(deftest take-how-many-test
(testing "We take two for a simple game"
(is (= 2 (take-how-many [1 2 1]))))
(testing "We take three from a spare game"
(is (= 3 (take-how-many [1 9 1]))))
(testing "We take three for a strike"
(is (= 3 (take-how-many [10 2 1])))))
(deftest drop-how-many-test
(testing "We drop two for a simple game"
(is (= 2 (drop-how-many [1 2 1]))))
(testing "We drop 2 from a spare game"
(is (= 2 (drop-how-many [1 9 1]))))
(testing "We drop one for a strike"
(is (= 1 (drop-how-many [10 2 1])))))
(deftest make-frames-test
(testing "Returns simple frame for simple game"
(is (= '((1 1)) (take 1 (make-frames [1 1 1 1])))))
(testing "Returns correct frame for game with spare"
(is (= '((1 9 1)) (take 1 (make-frames [1 9 1 1])))))
(testing "Returns correct frame for game with strikes"
(is (= '((10 10 10)) (take 1 (make-frames [10 10 10]))))))
(deftest make-game-test
(testing "Returns the correct game for a simple game"
(is (= '((1 1) (1 1) (1 1) (1 1) (1 1) (1 1) (1 1) (1 1) (1 1) (1 1))
(make-game (repeat 20 1)))))
(testing "Returns the correct game for a mixed game"
(is (= '((1 9 1) (1 2) (10 1 1) (1 1) (1 1) (1 1) (1 1) (1 1) (1 1) (1 1))
(make-game (concat [1 9 1 2 10] (repeat 14 1)))))))
(deftest frame-score-test
(testing "We can calculate the score of a frame"
(is (= 2 (frame-score [1 1])))
(is (= 11 (frame-score [1 9 1])))
(is (= 30 (frame-score [10 10 10])))))
(deftest scoring-tests
(testing "A gutter balls"
(is (= 0 (game-score (repeat 20 0)))))
(testing "All rolls are of one pin"
(is (= 20 (game-score (repeat 20 1)))))
(testing "Has a spare in the first round"
(is (= 29 (game-score (concat [1 9] (repeat 18 1))))))
(testing "Perfect game"
(is (= 300 (game-score (repeat 13 10)))))
(testing "Random game"
(is (= 145 (game-score [1 9 2 4 10 10 10 7 1 2 8 7 0 0 0 10 1 9])))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment