RosettaCodeData/Task/Happy-numbers/Clojure/happy-numbers-2.clj
2023-07-01 13:44:08 -04:00

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))