Skip to content

Instantly share code, notes, and snippets.

@mnzk
Created May 17, 2012 15:56
Show Gist options
  • Save mnzk/2719777 to your computer and use it in GitHub Desktop.
Save mnzk/2719777 to your computer and use it in GitHub Desktop.
inv-fizzbuzz.clj
;; 逆 FizzBuzz
;; ------------------------------------------------
;; :dependencies [[org.clojure/clojure "1.4.0"]
;; [org.clojure/core.incubator "0.1.0"]
;; [org.clojure/math.numeric-tower "0.0.1"]]
;; -------------------------------------------------
(ns inv-fizzbuzz.core
(:use [clojure.core.incubator :only (-?>>)])
(:use [clojure.math.numeric-tower :only (lcm)]))
(def word-num-pairs
[["fizz" 3]
["buzz" 5]])
(defn lcmx
[& xs]
(reduce (fn [acc x] (lcm acc x)) xs))
(def fizzbuzz-seq
(let [nils #(repeat % nil)
cyc #(cycle (cons %1 (nils (dec %2))))]
(->> (map (fn [[w n]] (cyc w n)) word-num-pairs)
(apply map str)
(drop 1))))
(def N (count (->> fizzbuzz-seq
(take (apply lcmx (map second word-num-pairs)))
(filter not-empty))))
(def INF Double/POSITIVE_INFINITY)
(defn fizzbuzz
[len]
(let [n (+ N (dec len))]
(->> (map list fizzbuzz-seq (range 1 INF))
(filter (comp not-empty first))
(take n))))
(defn inv-fizzbuzz
[& args]
(let [len (count args)]
(-?>> (fizzbuzz len)
(partition len 1)
(filter #(= args (map first %)))
not-empty
(map #(map second %))
(group-by #(- (last %) (first %)))
sort first second first)))
;;
;; examples -----------------------------------------------------
;;
;; (inv-fizzbuzz "fizz") ;=> (3)
;; (inv-fizzbuzz "fizzbuzz") ;=> (15)
;; (inv-fizzbuzz "fizz" "buzz") ;=> (9 10)
;; (inv-fizzbuzz "buzz" "fizz" "fizz") ;=> (5 6 9)
;; (inv-fizzbuzz "fizz" "fizz" "buzz") ;=> (6 9 10)
;; (inv-fizzbuzz "buzz" "fizz" "fizz" "buzz") ;=> (5 6 9 10)
;; (inv-fizzbuzz "fizz" "buzz" "fizz" "buzz") ;=> nil
;; (inv-fizzbuzz "fizz" "buzz" "fizz" "fizz" "buzz") ;=> (3 5 6 9 10)
;; (inv-fizzbuzz "fizz" "fizzbuzz" "fizz" "buzz") ;=> (12 15 18 20)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment