Ruby Hash#select method returns incomplete hashes -
i'm trying solve project euler question #21 in ruby.
let d(n) defined sum of proper divisors of n (numbers less n divide evenly n). if d(a) = b , d(b) = a, ≠ b, , b amicable pair , each of , b called amicable numbers. example, proper divisors of 220 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 , 110; therefore d(220) = 284. proper divisors of 284 1, 2, 4, 71 , 142; d(284) = 220. evaluate sum of amicable numbers under 10000.
i used brute-force method find solution finds sum of divisors of each number in [2,10000) range , pushes them hash object.
require 'prime' #method reference http://stackoverflow.com/questions/3398159/all-factors-of-a-given-number def factors_of(number) primes, powers = number.prime_division.transpose exponents = powers.map{|i| (0..i).to_a} divisors = exponents.shift.product(*exponents).map |powers| primes.zip(powers).map{|prime, power| prime ** power}.inject(:*) end #modified line divisors.sort![0..divisors.size-2] end ht=hash.new (2..10000).each |x| arr=factors_of(x) sum=arr.reduce(:+) ht[x]=sum end amicable=ht.select { |key, value| value==ht.key(key) && ht.key(key)!=key} puts amicable
output of code
{220=>284, 284=>220, 1184=>1210, 1210=>1184, 2620=>2924, 5020=>5564, 5564=>5020, 6232=>6368, 6368=>6232}
it finds amicable pairs except {2924=>2620}. other numbers have reverse pair except {2620=>2924}, {2924=>2620}. missing here? thoughts? thanks.
hash#key
returns first key given value.
a = ht.select{ |k,v| ht[v] == k && k!= v}
and keys rather value, because keys can't duplicates , things can trusted.
Comments
Post a Comment