How to resolve the algorithm Perfect numbers step by step in the Ruby programming language
How to resolve the algorithm Perfect numbers step by step in the Ruby programming language
Table of Contents
Problem Statement
Write a function which says whether a number is perfect.
A perfect number is a positive integer that is the sum of its proper positive divisors excluding the number itself. Equivalently, a perfect number is a number that is half the sum of all of its positive divisors (including itself).
Note: The faster Lucas-Lehmer test is used to find primes of the form 2n-1, all known perfect numbers can be derived from these primes using the formula (2n - 1) × 2n - 1. It is not known if there are any odd perfect numbers (any that exist are larger than 102000). The number of known perfect numbers is 51 (as of December, 2018), and the largest known perfect number contains 49,724,095 decimal digits.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Perfect numbers step by step in the Ruby programming language
This Ruby program finds and lists perfect numbers with 3 different algorithms.
- The first algorithm is a simple loop that calculates the sum of proper divisors of a number and checks if the sum equals the number itself.
- The second algorithm uses the inject method on an array of proper divisors to calculate the sum and compare it to the number.
- The third algorithm uses the Integer.sqrt method to find proper divisors and then checks if the sum of unique divisors equals twice the number.
The program also calculates and lists perfect numbers using Mersenne primes with a Lucas-Lehmer test. It does this by finding Mersenne prime numbers (which have the form 2^p - 1) and then multiplying their corresponding perfect numbers together.
In the demo section, the program lists perfect numbers up to 10000 and then tests the performance of the third algorithm by calculating a very large perfect number.
Here is a step-by-step explanation of the code:
- The perfect?(num) method uses a class variable @perfect_numerator to store a lazy enumerator that generates Mersenne prime numbers, and a class variable @perfects to store a list of the corresponding perfect numbers.
- The method calculates perfect numbers by multiplying the corresponding perfect numbers together.
- It lazily generates more perfect numbers as needed using the lazy enumerator @perfect_numerator.next.
- The method returns true if the given number is in the list of perfect numbers, and false otherwise.
- The demo section of the code demonstrates the perfect?(num) method by listing perfect numbers up to 10000 and then testing the performance of the method by calculating a very large perfect number.
Here are the outputs of the different sections of the code:
- The list of perfect numbers up to 10000:
6
28
496
8128
33550336
8589934592
137438691328
2305843008139952128
- The result of the performance test:
true
0.019803564999992645
This shows that the perfect?(num) method is efficient enough to calculate very large perfect numbers in a reasonable amount of time.
Source code in the ruby programming language
def perf(n)
sum = 0
for i in 1...n
sum += i if n % i == 0
end
sum == n
end
def perf(n)
n == (1...n).select {|i| n % i == 0}.inject(:+)
end
def perf(n)
divisors = []
for i in 1..Integer.sqrt(n)
divisors << i << n/i if n % i == 0
end
divisors.uniq.inject(:+) == 2*n
end
for n in 1..10000
puts n if perf(n)
end
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
You may also check:How to resolve the algorithm Element-wise operations step by step in the Standard ML programming language
You may also check:How to resolve the algorithm String length step by step in the Logo programming language
You may also check:How to resolve the algorithm User input/Graphical step by step in the Ring programming language
You may also check:How to resolve the algorithm Number reversal game step by step in the Quackery programming language
You may also check:How to resolve the algorithm Fibonacci n-step number sequences step by step in the Groovy programming language