Simple even and odd number loop in Ruby

Hello guys, I am trying to develop a simple loop in Ruby. You need to
type in a number. When this number is an “even” number, it will divide
it by 2. If it is an odd number, it will multiply it by 3. This goes in
a loop… so for instance if you type in number “20”, Ruby would write
an answer like this: 20, 10, 5, 15, 45,… infinitelly…always either
dividing or multiplying the number that it gets depending on whether it
is an odd or even number.

I tried so many things these days, but none of them were working.

I hope this is not homework. For example this would work:

def f n # this function calculates next number in your sequence
if n % 2 == 0 # n is even
return n / 2
else
return n * 3
end
end

num = gets.to_i # read in a number
while true # infinitely…
num = f(num) # find the next number
puts num # print it
sleep 1 # wait one second
end

Is there anything you don’t understand about this code?

– Matma R.

2012/2/5 Bartosz Dziewoński [email protected]:

num = gets.to_i # read in a number
while true # infinitely…
num = f(num) # find the next number
puts num # print it
sleep 1 # wait one second
end

There’s also Integer#even? and #odd?.
e.g.
if n.even?
return n / 2
else
return n * 3
end

On Sun, Feb 5, 2012 at 3:34 PM, Viera Tarcova
[email protected] wrote:

I tried so many things these days, but none of them were working.

Please show the code so we can give you concrete advice (vs. writing
the program for you).

Kind regards

robert

Thank you Bartosz, this is exactly what I was looking for. My loop was
not good at all. I am still learning. If you are interested in doing
online mentoring, please let me know. I would love to have such a good
mentor like you.

Bartosz Dziewoński wrote in post #1044167:

I hope this is not homework. For example this would work:

def f n # this function calculates next number in your sequence
if n % 2 == 0 # n is even
return n / 2
else
return n * 3
end
end

num = gets.to_i # read in a number
while true # infinitely…
num = f(num) # find the next number
puts num # print it
sleep 1 # wait one second
end

Is there anything you don’t understand about this code?

– Matma R.

Nice question, i was thinking of this too, would like to know how to
count the number of the output, instead of listing the numbers after
inputing a number

How would you make this loop stop when it reaches number one?

please is there any ideas on how to do this for a range of number say 2
to 5 and them count the number of counts before it ( that is the numbers
2,3,4,5 )gets to 1. after that be able to get the number with the
largest count?

for instance 3 gives count as follows

3,10,5,16,8,4,2,1

and for instance 4 gives count as follows

4,2,1

therefore between 2 to 5
the largest count is 8 which is produced by number 3

Viera Tarcova wrote in post #1044163:

Hello guys, I am trying to develop a simple loop in Ruby. You need to
type in a number. When this number is an “even” number, it will divide
it by 2. If it is an odd number, it will multiply it by 3. This goes in
a loop… so for instance if you type in number “20”, Ruby would write
an answer like this: 20, 10, 5, 15, 45,… infinitelly…always either
dividing or multiplying the number that it gets depending on whether it
is an odd or even number.

I tried so many things these days, but none of them were working.

This should provide some clarity with the following two examples:

If you wanted to print out only even integers from 0 - 20

i = 20
loop do
i -= 1
next if i % 2 != 0
print “#{i}”
break if i <= 0
end

(note technically it will only return even values up to 18, but you can
adjust the i = value as necessary)

If you wanted to print out only odd integers from 0 -20

i = 20
loop do
i -= 1
next if i % 2 == 0
print “#{i}”
break if i <= 0
end

(note technically it will only return odd values from 1 - 19)

On Mon, Feb 6, 2012 at 7:58 PM, Viera Tarcova
[email protected] wrote:

How would you make this loop stop when it reaches number one?

Instead of looping forever (while true), you should only loop until num
is 1.

Jesus.

This should provide some clarity with the following two examples:

If you wanted to print out only even integers from 0 - 20

i = 20
loop do
i -= 1
next if i % 2 != 0
print “#{i}”
break if i <= 0
end

(note technically it will only return even values up to 18, but you can
adjust the i = value as necessary)

If you wanted to print out only odd integers from 0 -20

i = 20
loop do
i -= 1
next if i % 2 == 0
print “#{i}”
break if i <= 0
end

(note technically it will only return odd values from 1 - 19)

On Sat, Feb 1, 2014 at 5:23 PM, Mike S. [email protected] wrote:

Remember that Ruby provides useful predicates for testing the even/odd -ness of
numbers, so the original poster’s problem could be solved like this which seems to
use terms close to those in the statement of the problem:

We can exploit more knowledge: the program will output in two phases:

  1. even numbers are printed; they are divided by two all the time
    until reaching an odd number
  2. odd numbers are printed until the end of time; each one is three
    times the number before

That also makes it clear that there is just one point where we can
reach 1 which was required as termination criterion.

print "Enter a starting number: "
num = Integer(gets)

while num.even?
puts num
num /= 2
end

puts num

loop do
puts num *= 3
end if num > 1

There are various variants how we can write the last part

variant

num == 1 or loop do
puts num *= 3
end

variant

if num > 1
loop do
puts num *= 3
end
end

variant

while num > 1
puts num *= 3
end

The last condition is a bit silly though as it tests too often
unnecessarily.

And it seems to produce the expected results for as long as I ran it, but I
don’t expect it to run infinitely because eventually my computer will run out of
memory to store a big Bignum!

:slight_smile:

Cheers

robert

On Jan 31, 2014, at 7:45 PM, Il Knowledge [email protected] wrote:

end
print “#{i}”
break if i <= 0
end

(note technically it will only return odd values from 1 - 19)

Remember that Ruby provides useful predicates for testing the even/odd
-ness of numbers, so the original poster’s problem could be solved like
this which seems to use terms close to those in the statement of the
problem:

#!/usr/bin/env ruby

print "Enter a starting number: "
num = Integer(gets)

loop do
puts num

if num.even?
num /= 2
else
num *= 3
end
end

And it seems to produce the expected results for as long as I ran it,
but I don’t expect it to run infinitely because eventually my computer
will run out of memory to store a big Bignum!

Hope this helps,

Mike

Mike S. [email protected]
http://www.stok.ca/~mike/

The “`Stok’ disclaimers” apply.

The original problem (if I understand it) seems like an ideal
opportunity to use an Enumerator. Here’s my go:

#!/usr/bin/env ruby

class TwoOrThree

attr_accessor :value

def initialize(value)
self.value = value
end

def each
return enum_for(:each) unless block_given?

loop do
  yield self.value

  if self.value.odd?
    self.value = self.value * 3
  else
    self.value = self.value / 2
  end

end

end

end

if ARGV.count < 2
puts “Usage: #{$0} START COUNT”
exit(-1)
end

start_value = Integer(ARGV.shift)
take_value = Integer(ARGV.shift)

e = TwoOrThree.new(start_value).each

p e.take(take_value)


$ bin/two_or_three 19 7
[19, 57, 171, 513, 1539, 4617, 13851]

$ bin/two_or_three 1 1
[1]

$ bin/two_or_three 0 3
[0, 0, 0]

$ bin/two_or_three -1 4
[-1, -3, -9, -27]

$ bin/two_or_three 20 20
[20, 10, 5, 15, 45, 135, 405, 1215, 3645, 10935, 32805, 98415, 295245,
885735, 2657205, 7971615, 23914845, 71744535, 215233605, 645700815]

On Tue, Feb 4, 2014 at 11:34 AM, Joel P. [email protected]
wrote:

    self.value = self.value / 2

attr_writer rather than a local variable.


Posted via http://www.ruby-forum.com/.

Yes.

I use them to keep myself clear. They are entirely superfluous for the
code.

puts even integers, count down…

i = 20
loop do
i -= 1
next if i % 2 == 1
puts “#{i}”
break if i <=2
end

puts odd integers, count down…

i = 20
loop do
i -= 1
next if i % 2 == 0
puts “#{i}”
break if i <=1
end

tamouse m. wrote in post #1135295:

def each
return enum_for(:each) unless block_given?

loop do
  yield self.value

  if self.value.odd?
    self.value = self.value * 3
  else
    self.value = self.value / 2
  end

end

end

end

I could be wrong, but aren’t there 4 superfluous “self.” in that code?
As far as I know, you’d only need to use self when you’re specifying the
attr_writer rather than a local variable.

I can’t believe nobody (unless I missed it) did a recursive function:

def calc(num)
puts num
num.even? ? calc(num / 2) : calc(num * 3) if num != 1
end

print "Enter Number: "
calc gets.to_i

It’s infinite…until the stack runs out in a few seconds… :slight_smile:

Rob