Skip to content

Instantly share code, notes, and snippets.

@KingCode
Created October 17, 2016 02:53
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 KingCode/17f56029834d47b4ffc47b8c4859f995 to your computer and use it in GitHub Desktop.
Save KingCode/17f56029834d47b4ffc47b8c4859f995 to your computer and use it in GitHub Desktop.
Unconditional FizzBuzz using a regex, for any multiples m1 (the fizz) < m2 (the buzz), m1 > 1 assumed
(defn fizzbuzz
([m1 m2 n]
(let [ c #(->> % vector (concat (-> %2 dec (repeat nil))) cycle)
fb-re #"Fizz|Buzz|FizzBuzz"]
(->> [(c "Fizz" m1), (c "Buzz" m2)]
(apply map
(fn [i m1 m2]
(or (re-matches fb-re (str m1 m2))
i))
(range 1 (inc n))))))
([n]
(fizzbuzz 3 5 n)))
@KingCode
Copy link
Author

KingCode commented Oct 17, 2016

;;
;; Spec'ing fizzbuzz as practice in learning clojure.spec
;;
(require '[clojure.spec :as s] '[clojure.spec.test :as stest])
(s/def ::posint (s/and integer? pos?))
(s/def ::fizzbuzz (s/and 
                   (s/alt :_1-arg ::posint
                          :_3-arg (s/cat :n1 (s/and ::posint #(< 1 %))
                                         :n2 ::posint
                                         :limit ::posint))
                   (fn [[_ {:keys [n1 n2 limit]}]]
                     (if n1
                       (< n1 n2 limit)
                       true))))

(def fizzbuzz-inout-valid? 
  #(let [mult1 (or (-> % :args :_3-arg :n1) 3)
         mult2 (or (-> % :args :_3-arg :n2) 5)
         n (or (-> % :args :_3-arg :limit)
               (-> % :args :_1-arg))]
     (and (= n (count (-> % :ret)))
          (->> (-> % :ret)
               (map (fn [i x]
                      (cond 
                        (= 0 (rem i mult1)(rem i mult2))
                        (= "FizzBuzz" x),                        
                        (zero? (rem i mult1))
                        (= "Fizz" x),
                        (zero? (rem i mult2))
                        (= "Buzz" x),
                        :else
                        (= i x)))
                    (range 1 (inc n)))
               (every? identity)))))

(s/fdef fizzbuzz 
        :args ::fizzbuzz
        :ret (s/* (s/alt :num ::posint
                         :fizz #(= "Fizz" %)
                         :buzz #(= "Buzz" %)
                         :fizzbuzz #(= "FizzBuzz")))
        :fn fizzbuzz-inout-valid?)

(stest/instrument `fizzbuzz)


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment