From: "Jesús Gabriel y Galán" Date: 2011-03-23T19:31:25+09:00 Subject: Re: Nil can't be coerced into Fixnum (TypeError) On Wed, Mar 23, 2011 at 10:57 AM, Mayank K. wrote: > I am trying to execute the following code and it seems like the array is > going out of bounds. Let me know where am I going wrong. > > class PrimeFactor >  def initialize(number) >    @number = number >  end > >  def primeFactors >    factors = Array.new >    (2..Math.sqrt(@number).ceil).each do |num| >      if ( @number % num == 0 ) >        factors.insert(factors.length,num) >      end >    end >    (0...factors.length).each do |i| >      prime = factors[i] >      factors = factors.select { |x| x == prime || x % prime !=0 } >    end > >    factors.compact.join(',') >  end > end > > prime = PrimeFactor.new(13195) > puts "#{prime.primeFactors}" > > C:\Temp\Study\Ruby>ruby --version > ruby 1.8.7 (2011-02-18 patchlevel 334) [i386-mingw32] > > C:\Temp\Study\Ruby>ruby prime.rb > prime.rb:16:in `%': nil can't be coerced into Fixnum (TypeError) >        from prime.rb:16:in `primeFactors' >        from prime.rb:16:in `select' >        from prime.rb:16:in `primeFactors' >        from prime.rb:14:in `each' >        from prime.rb:14:in `primeFactors' >        from prime.rb:24 The problem with your code is that you are modifying the factors array inside a precalculated iteration. Try adding some print statements in the last loop you'll see what's going on: [... snip...] p factors.length (0...factors.length).each do |i| p factors p i prime = factors[i] factors = factors.select { |x| x == prime || x % prime !=0 } end As you'll see, you are modifying the array, but the each loop is still going from 0 to 7. Another approach could be to set to nil the multiples of each factor, and then compact: factors.each do |factor| next if factor.nil? factors.each_with_index do |candidate,i| next if candidate == factor factors[i] = nil if candidate % factor == 0 end end BTW, your logic about the Math.sqrt being the top possible factor is wrong (that's used to know if a number is prime). For example, for 15, Math.sqrt(15) is less than 4, and 5 is a factor of 15 which your logic will skip. All in all, this works: class PrimeFactor def initialize(number) @number = number end def primeFactors factors = Array.new (2..@number).each do |num| if ( @number % num == 0 ) factors.insert(factors.length,num) end end p factors factors.each do |factor| next if factor.nil? factors.each_with_index do |candidate,i| next if candidate == factor next if candidate.nil? factors[i] = nil if candidate % factor == 0 end end factors.compact.join(',') end end #prime = PrimeFactor.new(13195) prime = PrimeFactor.new(ARGV.shift.to_i) puts "#{prime.primeFactors}" Maybe it can be further optimized, but you can start from here. This is the ouput for 13195: $ ruby prime_factors.rb 13195 [5, 7, 13, 29, 35, 65, 91, 145, 203, 377, 455, 1015, 1885, 2639, 13195] 5,7,13,29 Jesus.