TPR
TPR

Reputation: 111

Ruby's times method and for loop does the same thing, but what are the respective processes?

I have a paradigm where the purpose is to calculate "the total accumulated from 'variable from' to 'variable to'". I got two methods, but I don't know exactly what steps they go through.

The first is the times method. I don't understand what (to - from +1) produces and why (i + from)? Also, this code throws syntax error, unexpected end, expecting end-of-input, I don't know where I am going wrong .

from = 10
to = 20
sum = 0
  (to - from +1).times to |i|
    sum = sum + (i + from)
  end
puts sum

Then there is the for loop. I can't understand what is the "total sum accumulated from 'variable from' to 'variable to'", what is the process of adding it?

from = 10
to = 20
sum = 0
for i in from..to
  sum = sum + i
end
puts sum

I'm bad at math, thank you all.

Upvotes: 1

Views: 145

Answers (2)

dawg
dawg

Reputation: 103874

Using the IRB you can create an array that represents all the numbers from to to:

irb(main):043:0> from=10
=> 10
irb(main):044:0> to=20
=> 20
irb(main):047:0> a=(from..to).to_a
=> [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

You can get a sum of that array:

irb(main):048:0> a.sum
=> 165

And, actually, you don't need to make an array at all:

irb(main):049:0> (from..to).sum
=> 165

Side note. If you have three dots the last value of to is not included and that is a different sum obviously:

irb(main):053:0> (from...to).to_a
=> [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
irb(main):054:0> (from...to).sum
=> 145

So upto should really be called uptoandincluding:

irb(main):055:0> from.upto(to).to_a
=> [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

You can also use reduce or the alias inject either with a block or symbol to an operation to reduct a list the the pairwise application of the operator.

Example (reduce and inject are the same, but I usually use inject with a block or reduce with the parenthesis):

# block form where n is repeatedly added to an accumulator
irb(main):058:0> (from..to).inject{|sum, n| sum+n}
=> 165

# the operator + is repeated applied from the left to right 
irb(main):059:0> (from..to).reduce(:+)
=> 165

Upvotes: 3

Trinculo
Trinculo

Reputation: 2021

Here are a few idiomatic ways of solving this problem in Ruby. They might be a little easier to follow than the solution you proposed.

sum = 0

10.upto(20) do |i|
  sum = sum + i
end

For the first iteration of loop, i will = 10, the second, i will = 11 and so "up to" 20. Each time it will add the value of i to sum. When it completes, sum will have a value of 165.

Another way is this:

10.upto(20).sum

The reason this works is that 10.upto(20) returns an Enumerator. You can call sum on an Enumerator.

Upvotes: 2

Related Questions