Skip to content

Instantly share code, notes, and snippets.

@sztamas
Last active Sep 10, 2020
Embed
What would you like to do?
FizzBuzz without ifs
;; First solution
(defn fizz-buzz-or-number
[x]
(
["FizzBuzz" x x "Fizz" x "Buzz" "Fizz" x x "Fizz" "Buzz" x "Fizz" x x]
(mod x 15)))
(defn fizz-buzz
[xs]
(doseq [x (map fizz-buzz-or-number xs)]
(println x)))
(comment
(fizz-buzz (range 1 101))
(fizz-buzz [1 3 5 10 12 13 15])
)
;; Alternative solution.
;; I like this better, but it works better for a continuous range of numbers
(defn- make-seq
"Makes a sequence that returns name at each nth element and nil for others"
[name nth]
(cycle (concat (repeat (dec nth) nil) [name])))
(def fizzes (make-seq "Fizz" 3))
(def buzzes (make-seq "Buzz" 5))
(def fizzbuzzes (make-seq "FizzBuzz" 15))
(def first-non-nil #(some identity %&))
;; a lazy seq of FizzBuzzes, Fizzes, Buzzes, and numbers
(def fizz-buzz-seq
(map first-non-nil fizzbuzzes fizzes buzzes (iterate inc 1)))
(defn fizz-buzz-range
"Returns FizzBuzz elements from start (inclusive) to end
(exclusive), where start defaults to 1."
([end] (fizz-buzz-range 1 end))
([start end]
{:pre [(< start end)]}
(->> fizz-buzz-seq
(drop (dec start))
(take (- end start)))
))
;; The fizz-buzz-range works well for continuous ranges as the original FizzBuzz problem.
;; This function is to satisfy the spec in the newsletter (ie. pass in integers that could
;; be non-continuous)
(defn fizz-buzz-alternative
[xs]
(doseq [x (map #(first (fizz-buzz-range % (inc %))) xs)]
(println x)))
(comment
(fizz-buzz-range 101)
(fizz-buzz-range 100 201)
(fizz-buzz-alternative [1 3 5 9 10 12 13 15])
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment