2

I am pretty new to programming so bear with me, please.

So this is the code I have right now, I would like to know how to combine the two loops in the middle without changing the function of the program.

entry = " "

while entry != "q"
   print "enter a number: "
   num = gets.to_i

    for x in 1..num 
      sum = 0
    end

    for y in 1..x
      sum = sum + y
      puts sum
    end

    print "press any key to continue (q to quit): "
    entry = gets.chomp
end

Any help would be greatly appreciated!

Thank you!

Edit:

I guess I should clarify the function of this program; the user types in a number and then it calculates the value of each arithmetic series up to and including the number that the user put in.

So it if I type in 3 the result should display like this:

1

3

6

Sorry for the confusion!

Vroryn
  • 125
  • 6
  • 1
    Hello, and welcome to Stack Overflow. In the future, please use proper indentation: you will get more answers and faster if your code is correctly formatted; and please also explain the purpose of the program, and not expect the other users to run it or read it line by line to figure out what you are trying to do (potentially wrongly). – Amadan Feb 15 '17 at 06:43
  • Ok I will keep that in mind! Thank you – Vroryn Feb 15 '17 at 07:12
  • 1
    One thing to consider when writing Ruby is to avoid using `for`, although that is admittedly advice that sounds strange considering that's the backbone of most other languages. In Ruby `each` is the go-to iterator, and it has a number of variants, like `each_with_index` or `each_with_object` that make it quite flexible. `(1..num).each` or `(1..x).each do |x|` is how these would normally be expressed. The [Enumerable](http://ruby-doc.org/core-2.4.0/Enumerable.html) library is the shining gem in the middle of Ruby, so if you're learning it, have a look at the toys and tools in there. – tadman Feb 15 '17 at 07:18
  • I am literally just learning it, first programming language too, but thank you for your suggestions! It is quite overwhelming though at the beginning haha. – Vroryn Feb 15 '17 at 07:39

1 Answers1

2

Assuming that you want to calculate and puts a sum of numbers from 1 to the input number, I suggest following:

while entry != "q"
   print "enter a number: "
   num = gets.to_i
   puts (1..num).sum

   print "press any key to continue (q to quit): "
   entry = gets.chomp
end

For edited question solution could be:

while entry != "q"
   print "enter a number: "
   num = gets.to_i
   (1..num).inject(0) do |res, e|
     res += e
     p res
    end

   print "press any key to continue (q to quit): "
   entry = gets.chomp
end
Ilya
  • 13,337
  • 5
  • 37
  • 53
  • Thank you so much! Exactly what I was looking for! – Vroryn Feb 15 '17 at 07:10
  • Oh, I see [`sum`](http://blog.bigbinary.com/2016/11/02/ruby-2-4-introduces-enumerable-sum.html) made it into Ruby from Rails in 2.4. – tadman Feb 15 '17 at 07:16
  • @Vroryn, please, don't forget to accept my answer if it solved your problem. – Ilya Feb 15 '17 at 07:28
  • 2
    Considering that it's an arithmetic series, `puts n*(n+1)/2` is sufficient. – Cary Swoveland Feb 15 '17 at 07:44
  • 1
    @CarySwoveland, complexity is the same. Please, check [this](http://stackoverflow.com/questions/41449617/why-is-sum-so-much-faster-than-inject) SO question and answer. In my answer, you should not care about implementation and I think `sum` is more readable. – Ilya Feb 15 '17 at 07:51
  • 1
    Actually, I did encounter a problem that did not appear before. It states that there's a "nomethoderror" and that .sum is not defined. If it helps my version of ruby is 2.3 – Vroryn Feb 15 '17 at 08:42
  • @Vroryn, `sum` working from ruby v 2.4. You can use Carry's approach, or (since you're learning ruby) just upgrade ruby from 2.3 to 2.4 – Ilya Feb 15 '17 at 08:58
  • @Vroryn, or use `(1..n).inject(:+)` (less efficient) – Ilya Feb 15 '17 at 09:03
  • Sorry, I probably wasted your time, but do you know a step where it would also show all the arithmetic series up to and including the number that the user put in? (basically edited my post for more clarity) – Vroryn Feb 15 '17 at 10:01
  • @Vroryn, I've answered on the edited question, but next time, please, create a new question instead of fundamental editing of existing one. – Ilya Feb 15 '17 at 10:43
  • I don't understand what you mean by saying the complexity is the same. `n*(n+1)/2` is O(1) whereas `(1..n).sum` is O(n). No? – Cary Swoveland Feb 15 '17 at 15:22
  • @CarySwoveland, `sum` is optimized for Range objects. Complexity is O(1) – Ilya Feb 15 '17 at 15:25
  • I didn't know that until I read the q&a at the link you gave. It's curious that [Enumerable#sum](http://ruby-doc.org/core-2.4.0/Enumerable.html#method-i-sum) does that by checking the receiver rather than there being a method `Range#sum` (ala `Enumerable#select` vs `Hash#select`). Using the formula does make sense when compatibility with Ruby versions prior to 2.4 is required. – Cary Swoveland Feb 15 '17 at 15:54
  • @CarySwoveland, sure. Also, check [this](http://stackoverflow.com/questions/41636558/why-is-rangesum-defined-in-enumerable-module) question about defining `sum` method – Ilya Feb 15 '17 at 16:31