All factors of a given number
In Ruby, the prime
library gives you the factorization:
require 'prime'4800.prime_division #=> [[2, 6], [3, 1], [5, 2]]
To get that list of yours, you take the cartesian product of the possible powers:
require 'prime'def factors_of(number) primes, powers = number.prime_division.transpose exponents = powers.map{|i| (0..i).to_a} divisors = exponents.shift.product(*exponents).map do |powers| primes.zip(powers).map{|prime, power| prime ** power}.inject(:*) end divisors.sort.map{|div| [div, number / div]}endp factors_of(4800) # => [[1, 4800], [2, 2400], ..., [4800, 1]]
Note: In Ruby 1.8.7, you must require 'mathn'
instead of require 'prime'
. In Ruby 1.8.6, require 'backports/1.8.7/enumerable/inject'
or modify the inject
above...
I think this solution is nicer, especially because it doesn't perform so many loops, it doesn't require the Prime library and most importantly it runs til Math.sqrt(n)
.Here's the code:
class Integer def factors 1.upto(Math.sqrt(self)).select {|i| (self % i).zero?}.inject([]) do |f, i| f << i f << self / i unless i == self / i f end.sortend# Usage4800.factors
If you want to pair them up, just like in your example, you can use the following piece of code (which pairs up first with last and in case there's an odd number of factors, then the middle one is the square root):
class Integer def paired_up_factors a = self.factors l = a.length if l % 2 == 0 a[0, l / 2].zip(a[- l / 2, l / 2].reverse) else a[0, l / 2].zip(a[- l / 2 + 1, l / 2].reverse) + [a[l / 2], a[l / 2]] end endend# Usage4800.paired_up_factors