Calculation in a block

  • Thread starter Chandramouli Parasuraman
  • Start date
C

Chandramouli Parasuraman

Hi,

I'm new to ruby, and I am trying to add all the natural numbers below
one thousand that are multiples of 3 or 5. (exercise from ProjectEuler)

Here's my code:

class Array
def sumNumbers
sum = 0
self.each_with_index { |n, i|
if ((self % 3) == 0 || (self % 5) == 0)
sum += self
end
}
sum
end
end

numbers = [1..1000]
print "Sum of natural numbers till 1000 that are multiples of 3 or 5 is
" + numbers.sumNumbers

When I try to execute this, I get this error:

SumOfMults.rb:5:in `block in sumNumbers': undefined method `%' for
1..1000:Range
(NoMethodError)
from SumOfMults.rb:4:in `each'
from SumOfMults.rb:4:in `each_with_index'
from SumOfMults.rb:4:in `sumNumbers'
from SumOfMults.rb:14:in `<main>'

Not sure how self is actually treated as a Range. Can you please let
me know what's wrong in my code?

Thanks,
Mouli
 
A

Alex DeCaria

numbers = [1..1000]

In your code, numbers is an array with a single element. That single
element is a range of numbers from 1..1000. Instead, don't you want
numbers to be an array like [1, 2, 3, 4, 5, ..., 999, 1000]? You can
create this array by

numbers = Array.new(1000) { |i| i+1 }

--Alex
 
B

Brian Candler

Alex said:
numbers = [1..1000]

In your code, numbers is an array with a single element. That single
element is a range of numbers from 1..1000. Instead, don't you want
numbers to be an array like [1, 2, 3, 4, 5, ..., 999, 1000]? You can
create this array by

numbers = Array.new(1000) { |i| i+1 }

or:

numbers = (1..1000).to_a
 
R

Robert Dober

On Tue, May 4, 2010 at 12:59 PM, Chandramouli Parasuraman
I would be more rubymatic here ;)
1000.times.inject{ | sum_so_far, next_number |
if (next_number % 3).zero? || (next_number % 5).zero?
sum_so_far + next_number
else
sum_so_far
end
}

It might be exaggerated to use the implicit form of inject just
because the first value is zero (it will be passed to sum_so_far in
the first iteration)

inject(0){ | sum_so_far, next_number |
}
might have been more readable

HTH
R.
 
R

Robert Dober

numbers = (1..1000).to_a

or even [*1...1000] ( remark that 1000 must not be in the solution here ).
However I feel it is completely inadequate to the solution to create
an array of 999 numbers.

R.
 
C

Chandramouli Parasuraman

Great, now I understand. Works fine now with both Array.new(1000) {|i|
i+1} and the inject.

Thanks everyone.
 
T

Thomas Volkmar Worm

(1..1000).select{|n| n % 3 == 0 or n % 5 == 0}.inject{|sum,n| sum + n }
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top