Skip to content

Instantly share code, notes, and snippets.

@meganehouser
Created July 7, 2014 09:44
Show Gist options
  • Save meganehouser/6d3aae9d9a11ec66bad1 to your computer and use it in GitHub Desktop.
Save meganehouser/6d3aae9d9a11ec66bad1 to your computer and use it in GitHub Desktop.
Bowling Kata by Clojure
(defn spare? [t1 t2]
(= 10 (+ t1 t2)))
(defn spare-score [[next-pin]]
(+ 10 next-pin))
(defn strike? [t1]
(= 10 t1))
(defn strike-score [[first-pin second-pin]]
(+ 10 first-pin second-pin))
(defn last? [t2] (nil? t2))
(defn score
"compute bowling score"
[pins]
(loop [frame 10 score 0 rpins pins]
(if (= 0 frame)
score
(let [[t1 t2 & rest-pins] rpins]
(cond
(last? t2)
(recur 0 (+ score t2) [])
(spare? t1 t2)
(recur (dec frame) (+ score (spare-score rest-pins)) rest-pins)
(strike? t1)
(let [rest-pins (concat [t2] rest-pins)]
(recur (dec frame) (+ score (strike-score rest-pins)) rest-pins))
:else
(recur (dec frame) (+ score t1 t2) rest-pins))))))
(ns tddsample.core-test
(:require [clojure.test :refer :all]
[tddsample.core :refer :all]))
(defn- roll-many [n pins]
(apply vector (repeat n pins)))
(deftest bowling-game-kata
(testing "all-gutter"
(let [game-score (score (roll-many 20 0))]
(is (= 0 game-score))))
(testing "all-one"
(let [game-score (score (roll-many 20 1))]
(is (= 20 game-score))))
(testing "take-spare"
(let [game-score (score (concat [5 5 3] (roll-many 17 0)))]
(is (= 16 game-score))))
(testing "take-strike"
(let [game-score (score (concat [10 3 3] (roll-many 16 0)))]
(is (= 22 game-score))))
(testing "perfect-game"
(let [game-score (score (roll-many 12 10))]
(is (= 300 game-score)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment