# Calculation in a block

**URL:** <https://www.ruby-forum.com/t/calculation-in-a-block/188026>\
**Category:** Ruby\
**Created:** [May 4, 2010, 12:59pm UTC](https://www.ruby-forum.com/t/calculation-in-a-block/188026 "2010-05-04T12:59:29Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![contactmouli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/df705f/32.png) [@contactmouli](https://www.ruby-forum.com/u/contactmouli)\
**Post date:** [May 4, 2010, 12:59pm UTC](https://www.ruby-forum.com/t/calculation-in-a-block/188026/1 "2010-05-04T12:59:29Z")

</div>

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[i] % 3) == 0 || (self[i] % 5) == 0)  
sum += self[i]  
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`’

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

Thanks,  
Mouli

---

<div class="post-metadata">

**Author:** ![contactmouli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/df705f/32.png) [@contactmouli](https://www.ruby-forum.com/u/contactmouli)\
**Post date:** [May 4, 2010, 1:28pm UTC](https://www.ruby-forum.com/t/calculation-in-a-block/188026/2 "2010-05-04T13:28:43Z")

</div>

> 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

---

<div class="post-metadata">

**Author:** ![contactmouli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/df705f/32.png) [@contactmouli](https://www.ruby-forum.com/u/contactmouli)\
**Post date:** [May 4, 2010, 1:37pm UTC](https://www.ruby-forum.com/t/calculation-in-a-block/188026/3 "2010-05-04T13:37:03Z")

</div>

Alex DeCaria wrote:

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

---

<div class="post-metadata">

**Author:** ![contactmouli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/df705f/32.png) [@contactmouli](https://www.ruby-forum.com/u/contactmouli)\
**Post date:** [May 4, 2010, 1:41pm UTC](https://www.ruby-forum.com/t/calculation-in-a-block/188026/4 "2010-05-04T13:41:02Z")

</div>

On Tue, May 4, 2010 at 12:59 PM, Chandramouli Parasuraman  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:  
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.

---

<div class="post-metadata">

**Author:** ![contactmouli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/df705f/32.png) [@contactmouli](https://www.ruby-forum.com/u/contactmouli)\
**Post date:** [May 4, 2010, 1:43pm UTC](https://www.ruby-forum.com/t/calculation-in-a-block/188026/5 "2010-05-04T13:43:58Z")

</div>

On Tue, May 4, 2010 at 1:37 PM, Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

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

---

<div class="post-metadata">

**Author:** ![contactmouli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/df705f/32.png) [@contactmouli](https://www.ruby-forum.com/u/contactmouli)\
**Post date:** [May 13, 2010, 1:51am UTC](https://www.ruby-forum.com/t/calculation-in-a-block/188026/6 "2010-05-13T01:51:26Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![contactmouli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/df705f/32.png) [@contactmouli](https://www.ruby-forum.com/u/contactmouli)\
**Post date:** [May 4, 2010, 2:16pm UTC](https://www.ruby-forum.com/t/calculation-in-a-block/188026/7 "2010-05-04T14:16:21Z")

</div>

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

Thanks everyone.
