Daniel Martin <martin / snowplow.org> writes: > Here's my solution to find happy bases - note that I don't find any > happy bases (aside from 2 and 4) before I run out of memory, somewhere > near base 1700. It wouldn't surprise me if no other happy bases > exist. And here's a faster version, and I also corrected the "Error" to "Exception" mistake I'd made in my earlier version. This version makes it through bases 2 - 100 in the blink of an eye, but really starts to slow down around base 700. I haven't had a chance to run this one as far as it can go without running out of memory; maybe later today. Still haven't found any other happy bases... #! /usr/bin/env ruby require 'narray' def dodigsum(initial, base) tmp = initial / (base ** NArray.to_na([[0],[1],[2]])) # I would use mod!, but my copy of narray doesn't have mod! tmp = tmp % base tmp.mul!(tmp) initial.fill!(0).add!(tmp.sum(1)) end def checkbase(base = 10) # As shown on the list, you're guaranteed that eventually every # number will be two digits or less, and once there the highest # you'll ever get again is... checklimit = 2*(base-1)*(base-1) check = NArray.int(checklimit + 1).indgen! check_initial = check.dup dodigsum(check,base) checkp = check.dup while true do if check.eq(check_initial).count_true > 2 #lp = check.mul!(check.eq(check_initial)).mask(check.ge(2)).min #puts "#{base} has a loop on #{lp}" print (base % 100 > 0 ? "." : "x") break end if check.le(1).count_true > checklimit puts "#{base} is a happy base" break end check[0] = check[checkp] end end 2.upto(3000) { |b| begin checkbase(b) GC.start if (b > 300 and b % 5 == 0) sleep(1) if (b % 100 == 0) rescue Interrupt puts "Checking #{b}" checkbase(b) rescue Exception => e puts "Bailing on #{b}" raise e end } __END__ -- s=%q( Daniel Martin -- martin / snowplow.org puts "s=%q(#{s})",s.map{|i|i}[1] ) puts "s=%q(#{s})",s.map{|i|i}[1]