def sum_of_divisors(num)
divisors = [1]
(2..Math::sqrt(num)).each do |e|
if num % e == 0
divisors << e
divisors << num / e
end
end
divisors.uniq.inject { |sum,e| sum += e }
end
amicable_pairs = {}
amicable_pairs.instance_eval do
def has_calculated(num)
self.has_key?(num) or self.has_value?(num)
end
end
(1..10000).each do |num|
unless amicable_pairs.has_calculated(num)
candidate = sum_of_divisors(num)
amicable_pairs[num] = candidate if num == sum_of_divisors(candidate) and num != candidate
end
end
amicable_pairs.sort.each { |k,v| puts "#{k} #{v}" }
Below code is a little bit different version:
Fixnum.class_eval do
@sum_of_divisors = nil
def sum_of_divisors
unless @sum_of_divisors
divisors = [1]
(2..Math::sqrt(self)).each do |e|
if self % e == 0
divisors << e
divisors << self / e
end
end
@sum_of_divisors = divisors.uniq.inject { |sum,e| sum += e }
end
@sum_of_divisors
end
def has_amicable_partner?
self == self.sum_of_divisors.sum_of_divisors and !self.is_perfect?
end
def amicable_partner
self.sum_of_divisors
end
def is_perfect?
self == self.sum_of_divisors
end
end
amicable_pairs = {}
amicable_pairs.instance_eval do
def has_calculated(num)
self.has_key?(num) or self.has_value?(num)
end
end
(1..10000).each do |num|
unless amicable_pairs.has_calculated(num)
amicable_pairs[num] = num.amicable_partner if num.has_amicable_partner? and !num.is_perfect?
end
end
amicable_pairs.sort.each { |k,v| puts "#{k} #{v}" }



덧글