Skip to content

Instantly share code, notes, and snippets.

@mdwhatcott
Created August 3, 2021 20:34
Show Gist options
  • Select an option

  • Save mdwhatcott/90df917528bd7cd6d563cd18dc4a60a2 to your computer and use it in GitHub Desktop.

Select an option

Save mdwhatcott/90df917528bd7cd6d563cd18dc4a60a2 to your computer and use it in GitHub Desktop.
functional-bowling.clj
(ns bowling.core-spec
(:require [speclj.core :refer :all]))
(def all-pins 10)
(def all-frames 10)
(defn rolls->frames [rolls]
(cond
(empty? rolls) []
(= all-pins (first rolls))
(cons (take 3 rolls) (lazy-seq (rolls->frames (rest rolls))))
(= all-pins (+ (first rolls) (second rolls)))
(cons (take 3 rolls) (lazy-seq (rolls->frames (drop 2 rolls))))
:else
(cons (take 2 rolls) (lazy-seq (rolls->frames (drop 2 rolls))))))
(defn bowl [rolls]
(->> rolls ; 1. [5 5 3 2 1 0 10 3 4 0 0 0 0 0 0 0 0 0 0]
rolls->frames ; 2. [[5 5 3] [3 2] [1 0] [10 3 4] [3 4] [0 0] [0 0] [0 0] [0 0] [0 0]]
(take all-frames) ; 3. No change in this case, but important when 10th frame has 3 throws!
flatten ; 4. [5 5 3 3 2 1 0 10 3 4 3 4 0 0 0 0 0 0 0 0 0 0]
(apply +))) ; 5. Sum: 43
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn roll-many [times pins]
(take times (cycle [pins])))
(describe "bowling game"
(it "gutter game"
(let [game (roll-many 20 0)]
(should= 0 (bowl game))))
(it "all ones"
(let [game (roll-many 20 1)]
(should= 20 (bowl game))))
(it "spare"
(let [game (concat [5 5 3 1] (roll-many 16 0))]
(should= 17 (bowl game))))
(it "strike"
(let [game (concat [10 3 4 1] (roll-many 15 0))]
(should= 25 (bowl game))))
(it "perfection"
(let [game (roll-many 12 10)]
(should= 300 (bowl game)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment