var primes = Enumerator({ |callback| static primes = Hash() var p = 2 loop { callback(p) p = (primes{p} := p.next_prime) } }) func factors(remainder) { remainder == 1 && return([remainder]) gather { primes.each { |factor| if (factor*factor > remainder) { take(remainder) if (remainder > 1) break } while (factor.divides(remainder)) { take(factor) break if ((remainder /= factor) == 1) } } } } func is_smith_number(n) { !n.is_prime && (n.digits.sum == factors(n).join.to_i.digits.sum) } var s = range(2, 10_000).grep { is_smith_number(_) } say "#{s.len} Smith numbers below 10_000" say "First 10: #{s.first(10)}" say "Last 10: #{s.last(10)}"