From: Phrogz Date: 2006-09-03T22:45:35+09:00 Subject: Re: Happy Numbers (#93) Here are my two solutions. Both take arbitrary bases. Neither counts the number of steps between a number and its happiness. The hash-based one is based on the auto-memoizing idea previously discussed on this list for a speedy fibonacci calculation. The core of both calculations is calculating the next happy step via: num.to_s(base).split('').map{ |c| c.to_i(base)**2 }.inject{ |s,i| s+i } class Integer @@happysteps = Hash.new{ |k,v| k[v] = {} } def happy?( base=10 ) seen = {} num = self until num==1 or seen[ num ] seen[ num ] = true num = num.to_s(base).split('').map{ |c| c.to_i(base)**2 }.inject{ |s,i| s+i } end num == 1 end end happy = Hash.new{ |h1,base| h1[ base ] = Hash.new{ |h2, n| if n == 1 h2[ 1 ] = true else h2[ n ] = :not_happy sum_of_squares = n.to_s(base).split('').map{ |c| c.to_i(base)**2 }.inject{ |s,i| s+i } if sum_of_squares == 1 h2[ n ] = true else subn = h2[ sum_of_squares ] if subn == true h2[ n ] = true elsif subn == false || subn == :not_happy h2[ n ] = h2[ sum_of_squares ] = false end end end } } range = 1..1000 puts "How many Happy numbers between #{range}?" 3.upto(36){ |base| puts "Base #{base}: #{range.select{|i| happy[ base ][ i ] }.length} happy numbers." puts "Base #{base}: #{range.select{|i| i.happy?( base ) }.length} happy numbers." }