Created
May 5, 2012 03:09
-
-
Save zmaril/2599321 to your computer and use it in GitHub Desktop.
Inverse fizzbuzz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;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