Skip to content

Instantly share code, notes, and snippets.

@stuarthalloway
Created August 12, 2017 22:41
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save stuarthalloway/01a2b7233b1285a8b43dfc206ba0036e to your computer and use it in GitHub Desktop.
Save stuarthalloway/01a2b7233b1285a8b43dfc206ba0036e to your computer and use it in GitHub Desktop.
;; try this form-by-form at a REPL
(require '[clojure.spec.alpha :as s])
;; create an inline DSL to describe the FizzBuzz world
(defmacro divides-by
[nm n]
`(s/def ~nm (s/and pos-int? #(zero? (mod % ~n)))))
;; specify FizzBuzz
(divides-by ::fizz 3)
(divides-by ::buzz 5)
(divides-by ::fizzbuzz 15)
;; try it out
(s/conform ::fizz 4)
(s/exercise ::fizz)
;; specify all of FizzBuzz so it can generate
(s/def ::fizzbuzznum
(s/and (s/or :name (s/and (s/or :FizzBuzz ::fizzbuzz :Buzz ::buzz :Fizz ::fizz)
(s/conformer (comp name first)))
:num pos-int?)
(s/conformer second)))
;; take it for a stroll...
(s/exercise ::fizzbuzznum 25)
;; oops, almost forgot to solve the problem...
(def fizzbuzz-transducer (map (partial s/conform ::fizzbuzznum)))
;; ...lazily generate FizzBuzz for all the integers
(set! *print-length* 100)
(eduction fizzbuzz-transducer (range 1 101))
;; load a unit test library
(require '[clojure.edn :as edn])
;; comprehensive test suite
(assert (= (eduction fizzbuzz-transducer (range 1 101))
(-> "https://gist.githubusercontent.com/stuarthalloway/ad1041d65b84626e5b8009e51ad69260/raw" slurp edn/read-string)))
;; Since FizzBuzz is used for interviews, here is an interview question:
;; Given the implementation above, why is it desirable that this number be small?
(Math/pow (/ 14.0 15) 100)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment