All factors of a given number All factors of a given number ruby ruby

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...


 def divisors_of(num)   (1..num).select { |n|num % n == 0} end


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