Perfect numbers: Difference between revisions

Content added Content deleted
(→‎{{header|Ruby}}: added fast method (Lucas-Lehmer))
Line 1,523: Line 1,523:
496
496
8128
8128
</pre>
===Fast (Lucas-Lehmer)===
Generate and memoize perfect numbers as needed.
<lang ruby>require "prime"

def mersenne_prime_pow?(p)
# Lucas-Lehmer test; expects prime as argument
return true if p == 2
m_p = ( 1 << p ) - 1
s = 4
(p-2).times{ s = (s**2 - 2) % m_p }
s == 0
end

@perfect_numerator = Prime.each.lazy.select{|p| mersenne_prime_pow?(p)}.map{|p| 2**(p-1)*(2**p-1)}
@perfects = @perfect_numerator.take(1).to_a

def perfect?(num)
@perfects << @perfect_numerator.next until @perfects.last >= num
@perfects.include? num
end

# demo
p (1..10000).select{|num| perfect?(num)}
t1 = Time.now
p perfect?(13164036458569648337239753460458722910223472318386943117783728128)
p Time.now-t1
</lang>
{{out}}
<pre>
[6, 28, 496, 8128]
true
0.001053954
</pre>
</pre>