Divisors of 42 are : 1, 2, 3, 6, 7, 14, 21, 42. These divisors squared are: 1, 4, 9, 36, 49, 196, 441, 1764. The sum of the squared divisors is 2500 which is 50 * 50, a square!
Given two integers \$m\$, \$n\$ (\$1 \le m \le n\$) we want to find all integers between m and n whose sum of squared divisors is itself a square. 42 is such a number.
The result will be an array of arrays, each subarray having two elements, first the number whose squared divisors is a square and then the sum of the squared divisors.
I started learning Ruby two weeks ago so I don't know much. This is my first programming language.
Is it possible to rewrite the below code so it runs faster? It currently times out at n>9999.
def list_squared(m, n)
r = (m..n).to_a.map { |z| (1..z).select { |x| z % x == 0} }
#returns the divisors of each number in an array of arrays
squarenumbers = r.map { |x| x.map { |c| c**2 }.inject(:+) }.select { |x| Math.sqrt(x) % 1 == 0 }
#this finds all integers between m and n whose sum of squared divisors is itself a square
booleans = r.map { |x| x.map { |c| c**2 }.inject(:+) }.map { |x| Math.sqrt(x) % 1 == 0 }
#returns an array of booleans.
indexer = booleans.map.with_index{|x, i| i if x == true }.compact
#returns the index of each of the true values in booleans as an array
unsqr = indexer.map { |x| (m..n).to_a[x] }
#returns the numbers whose squared divisors is a square in an array
unsqr.zip(squarenumbers)
#merges the two arrays together, element for element and creates an array of arrays
end
#for m = 1 and n = 1000 the result would be
#[[1, 1], [42, 2500], [246, 84100], [287, 84100], [728, 722500]]