#* http://rosettacode.org/wiki/Happy_numbers
  Find and print the first 8 "happy" numbers
*#

includes :set :seq

happiness = set.new 1
sadness = set.new

sum_of_squares_of_digits = { num |
  num.to_s.dice.reduce 0 { sum, n | sum = sum + n.to_i ^ 2 }
}

happy? = { n, seen = set.new |
  when { happiness.include? n } { happiness.merge seen << n; true }
    { sadness.include? n } { sadness.merge seen; false }
    { seen.include? n } { sadness.merge seen; false }
    { true } { seen << n; happy? sum_of_squares_of_digits(n), seen }
}

happies = seq.new({ n | n + 1} 1).select(->happy?)

p "First eight happy numbers: #{happies.take(8).to_array}"
p "Happy numbers found: #{happiness.to_array.sort}"
p "Sad numbers found: #{sadness.to_array.sort}"