Skip to content

Instantly share code, notes, and snippets.

@zmaril
Created May 5, 2012 03:09
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 zmaril/2599321 to your computer and use it in GitHub Desktop.
Save zmaril/2599321 to your computer and use it in GitHub Desktop.
Inverse fizzbuzz
;;Solution to inverse fizzbuzz
;;http://www.jasq.org/2/post/2012/05/inverse-fizzbuzz.html
;;TODO: Uses the top comment from hacker news
(ns faster.core
(:use clojure.test))
;;Simple fizzbuzz function
(defn fizzbuzz [n]
(str (when (zero? (mod n 3)) "fizz")
(when (zero? (mod n 5)) "buzz")))
(def pattern
"The recurrence pattern in the output of fizzbuzz. Found
using (filter #(not (zero? (count %))) (map fizzbuzz (range 1
16))). Copied and pasted for clarity's sake."
["fizz" "buzz" "fizz" "fizz" "buzz" "fizz" "fizzbuzz"])
(def infinite-fizz (filter #(not (zero? (count (fizzbuzz %))))
(iterate inc 1)))
(defn inverse-fizzbuzz-with-fizzbuzz
[lst]
(let [
fizz-index (.indexOf lst "fizzbuzz")
pattern-size (count pattern)
more-than-enough (take (+ pattern-size
(- (count lst) fizz-index 1))
infinite-fizz)
fizzbuzzes (drop (- pattern-size fizz-index 1) more-than-enough)
start (first fizzbuzzes)
last (last fizzbuzzes)]
(range start (inc last))))
(defn inverse-fizzbuzz-without-fizzbuzz
[lst]
(let [points (take-while (partial > 100) infinite-fizz)
pairs-of-points (for [i points j points :when (<= i j)] [i j] )
fizz-list (fn [[start end]]
(filter #(> (count %) 0)
(map fizzbuzz (range start (inc end)))))
fizzed-lists (map #(vector % (fizz-list %)) pairs-of-points)
selected-lists (map first (filter #(= lst (second %)) fizzed-lists))
sorted-list (sort #(> (apply - %1)
(apply - %2))
selected-lists)
selection (first sorted-list)
]
(range (first selection) (inc (second selection)))))
(defn inverse-fizzbuzz
[lst]
(if (contains? (set lst) "fizzbuzz")
(inverse-fizzbuzz-with-fizzbuzz lst)
(inverse-fizzbuzz-without-fizzbuzz lst)))
;;It comes with tests!
(deftest inverse-fizzbuzz-test
(is (= [3] (inverse-fizzbuzz ["fizz"])))
(is (= [5] (inverse-fizzbuzz ["buzz"])))
(is (= [15] (inverse-fizzbuzz ["fizzbuzz"])))
(is (= [9, 10] (inverse-fizzbuzz ["fizz","buzz"])))
(is (= [5, 6] (inverse-fizzbuzz ["buzz","fizz"])))
(is (= [3, 4, 5, 6] (inverse-fizzbuzz ["fizz", "buzz","fizz"])))
(is (= [6,7,8,9] (inverse-fizzbuzz ["fizz","fizz"])))
(is (= (range 3 31) (inverse-fizzbuzz (into pattern pattern))))
;;It throws an exception now. How do I say, I want an exception?
;;(is (= nil (inverse-fizzbuzz ["buzz", "fizz","buzz"])))
(is (= [6,7,8,9,10] (inverse-fizzbuzz ["fizz","fizz","buzz"]))))
(defn -main
"Run the tests. Those are all that count."
[& args]
(run-tests))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment