35 lines
938 B
Clojure
35 lines
938 B
Clojure
(require '[clojure.set :refer [union]])
|
|
|
|
(def ^{:private true} cache {:happy (atom #{}) :sad (atom #{})})
|
|
|
|
(defn break-apart [n]
|
|
(->> (str n)
|
|
(map str)
|
|
(map #(Long/parseLong %))))
|
|
|
|
(defn next-number [n]
|
|
(->> (break-apart n)
|
|
(map #(* % %))
|
|
(apply +)))
|
|
|
|
(defn happy-or-sad? [prev n]
|
|
(cond (or (= n 1) ((deref (:happy cache)) n)) :happy
|
|
(or ((deref (:sad cache)) n) (some #(= % n) prev)) :sad
|
|
:else :unknown))
|
|
|
|
(defn happy-algo [n]
|
|
(let [get-next (fn [[prev n]] [(conj prev n) (next-number n)])
|
|
my-happy-or-sad? (fn [[prev n]] [(happy-or-sad? prev n) (conj prev n)])
|
|
unknown? (fn [[res nums]] (= res :unknown))
|
|
[res nums] (->> [#{} n]
|
|
(iterate get-next)
|
|
(map my-happy-or-sad?)
|
|
(drop-while unknown?)
|
|
first)
|
|
_ (swap! (res cache) union nums)]
|
|
res))
|
|
|
|
(def happy-numbers (->> (iterate inc 1)
|
|
(filter #(= :happy (happy-algo %)))))
|
|
|
|
(println (take 8 happy-numbers))
|