Skip to content

Instantly share code, notes, and snippets.

@wjlroe
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wjlroe/90b00fda936fd510ddd6 to your computer and use it in GitHub Desktop.
Save wjlroe/90b00fda936fd510ddd6 to your computer and use it in GitHub Desktop.
Fizzbuzz without control structures
(ns fizzbuzzable.core-test
(:require [clojure.test :refer :all]
[clojure.test.check.clojure-test :refer [defspec]]
[clojure.test.check :as tc]
[clojure.test.check.generators :as gen]
[clojure.test.check.properties :as prop]
[fizzbuzzable.core :refer :all]))
(defn boring-fizzbuzz
[n]
(for [i (range 1 (inc n))]
(cond
(and (zero? (mod i 5))
(zero? (mod i 3))) "fizzbuzz"
(zero? (mod i 5)) "buzz"
(zero? (mod i 3)) "fizz"
:else (str i))))
(defn real-take-nth
[n col]
(map second
(filter (fn [[i v]]
(zero? (mod (inc i) n)))
(map vector
(range 0 (count col))
col))))
(defspec fizzbuzz-works 100
(prop/for-all [v gen/int]
(= (fizzbuzz v)
(boring-fizzbuzz v))))
(defspec divisible-by-five 100
(prop/for-all [v gen/int]
(every? #(re-find #"buzz" %)
(real-take-nth 5 (fizzbuzz v)))))
(defspec divisible-by-three 100
(prop/for-all [v gen/int]
(every? #(re-find #"fizz" %)
(real-take-nth 3 (fizzbuzz v)))))
(defspec divisible-by-three-and-five 100
(prop/for-all [v gen/int]
(every? #(= "fizzbuzz" %)
(real-take-nth 15 (fizzbuzz v)))))
(ns fizzbuzzable.core)
(defprotocol Fizzbuzzable
(next-num [this]))
(defrecord G3 [i]
Object
(toString [_] "fizzbuzz"))
(defrecord G2 [i]
Object
(toString [_] (str i))
Fizzbuzzable
(next-num [_]
(G3. (inc i))))
(defrecord G1 [i]
Object
(toString [_] (str i))
Fizzbuzzable
(next-num [_]
(G2. (inc i))))
(defrecord F2 [i]
Object
(toString [_] "fizz")
Fizzbuzzable
(next-num [_]
(G1. (inc i))))
(defrecord F1 [i]
Object
(toString [_] (str i))
Fizzbuzzable
(next-num [_]
(F2. (inc i))))
(defrecord E1 [i]
Object
(toString [_] "buzz")
Fizzbuzzable
(next-num [_]
(F1. (inc i))))
(defrecord D3 [i]
Object
(toString [_] "fizz")
Fizzbuzzable
(next-num [_]
(E1. (inc i))))
(defrecord D2 [i]
Object
(toString [_] (str i))
Fizzbuzzable
(next-num [_]
(D3. (inc i))))
(defrecord D1 [i]
Object
(toString [_] (str i))
Fizzbuzzable
(next-num [_]
(D2. (inc i))))
(defrecord C1 [i]
Object
(toString [_] "fizz")
Fizzbuzzable
(next-num [_]
(D1. (inc i))))
(defrecord B2 [i]
Object
(toString [_] "buzz")
Fizzbuzzable
(next-num [_]
(C1. (inc i))))
(defrecord B1 [i]
Object
(toString [_] (str i))
Fizzbuzzable
(next-num [_]
(B2. (inc i))))
(defrecord A3 [i]
Object
(toString [_] "fizz")
Fizzbuzzable
(next-num [_]
(B1.
(inc i))))
(defrecord A2 [i]
Object
(toString [_] (str i))
Fizzbuzzable
(next-num [_]
(A3. (inc i))))
(defrecord A1 [i]
Object
(toString [_] (str i))
Fizzbuzzable
(next-num [this]
(A2. (inc i))))
(extend-type G3
Fizzbuzzable
(next-num [this]
(A1. (inc (:i this)))))
(defn fizzbuzz
([]
(fizzbuzz 100))
([limit]
(map str (take limit (iterate next-num (A1. 1))))))
(defn -main
[]
(doseq [val (fizzbuzz 100)]
(println val)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment