# Re: Happy Numbers (#93)

**URL:** <https://www.ruby-forum.com/t/re-happy-numbers-93/67602>\
**Category:** Ruby\
**Created:** [September 5, 2006, 4:34pm UTC](https://www.ruby-forum.com/t/re-happy-numbers-93/67602 "2006-09-05T16:34:54Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![davidtl](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/35a633/32.png) [@davidtl](https://www.ruby-forum.com/u/davidtl)\
**Post date:** [September 5, 2006, 4:34pm UTC](https://www.ruby-forum.com/t/re-happy-numbers-93/67602/1 "2006-09-05T16:34:54Z")

</div>

Modified my first solution to make it thread safe.  
Also include the solution for finding happiest between 1 and 1,000,000.

class Integer  
def digits(base = 10)  
return [self] if self \< base  
self.divmod(base).inject { |div, mod| div.digits(base) \<\< mod }  
end

def happy?(base = 10)  
\_happy?([], base)  
end

protected

def \_happy?(happy\_list, base)  
return false if happy\_list.include?(self)  
happy\_list \<\< self  
return happy\_list if self == 1  
self.digits(base).inject(0) { |n, d| n + d\*d }.\_happy?(happy\_list,  
base)  
end  
end

# Find happiest between 1 and 1\_000\_000

# 

# 1\_000\_000 is not the happiest. ( [1000000, 1] )

# So, all numbers \<= 999\_999 after first iteration

# will \<= (9\*\*2) \* 6 ( = 486 )

# 

# Also the rule to determine happy for number

# 123 is the same as 231, 321, 12300, 10230 … etc

# So, for all 2 digits numbers, we only need to check 55 numbers,

# for all 3 digits numbers, we only need to check 220 numbers … etc

# 

# Here will not use this optimization, because the happiest does not

# so slow ( at least on my PC ) to find it …

if **FILE** == $0

# find all happy numbers ( max happy rank ) between 1 … (9\*\*2)\*6

rate = 1  
list = [1]  
max = (9\*\*2) \* 6  
(1…max).each do |n|  
happy = n.happy?  
next unless happy  
if happy.size == rate  
list \<\< n  
elsif happy.size \> rate  
rate = happy.size  
list = [n]  
end  
end

happiest = ((max+1)…1\_000\_000).each do |n|  
break n if list.include?(n.digits.inject(0) { |sum, d| sum + d\*d })  
end

puts “the happiest number between 1 and 1,000,000 is #{happiest}”  
p happiest.happy?  
end
