Skip to content

Instantly share code, notes, and snippets.

@taylorlapeyre
Last active August 29, 2015 14:20
Show Gist options
  • Save taylorlapeyre/5cdcf15a6fbabff1c5af to your computer and use it in GitHub Desktop.
Save taylorlapeyre/5cdcf15a6fbabff1c5af to your computer and use it in GitHub Desktop.
Happy Numbers
(defn square [x] (* x x))
(defn happy
"Given a number, returns a new number that is the result of summing
the squares of its digits"
[x]
(let [characters (map str (seq (str x)))
digits (map #(Integer/parseInt %) characters)]
(reduce + (map square digits))))
(defn happy-sequence
"Given a starting number, produces recursive happy numbers up to the
point where the sequence begins repeating infinitely"
[starting-number]
(let [happy-sequence (iterate happy starting-number)
used-numbers (atom #{})
new-number? (fn [x]
(when-not (@used-numbers x)
(swap! used-numbers conj x)))]
(take-while new-number? happy-sequence)))
(defn is-happy?
"True if the last iteration of the number's happy sequence is 1"
[x]
(= 1 (last (happy-sequence x))))
(happy-sequence 41)
; => (41 17 50 25 29 85 89 145 42 20 4 16 37 58)
(is-happy? 41)
; => false
(is-happy? 10)
; => true
@rauhs
Copy link

rauhs commented May 4, 2015

Check out reductions + distinct?, then you don't need the atom. Though, a little less efficient since it'll re-run distinct every time. The set approach is better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment