Control Structures

Discussion in 'Ruby' started by Trent Jones, Dec 1, 2008.

  1. Trent Jones

    Trent Jones Guest

    G'day all, I'm new to Ruby, been studying Software Engineering at
    university and they have been teaching in Java.

    As such, I'm trying to learn as few of the basics by going through and
    comverting smoe of the programs I made into Ruby. At the moment, I'm
    struggling a bit with the control structures, if-then-else is fine,
    switch/case is fine. I'm just a little confused about the for and
    while/dowhile loops.

    I'm trying to make a "infinite monkeys" simulation, i.e. initiate an
    array of 'x' length and then fill it with random numbers, then check to
    see if those numbers are in order, if not, repeat the process. More or
    less anyway.

    At the moment I'm using this loop to fill the array:
    for num in (0..Integer(a))
    monkey[num]=Integer(rand*5+1)
    end
    variable 'a' is input by the user to determine how big a sequence, i.e.
    5 numbers in a row.

    Is this the easiest way of doing things?
    And then I could use a similar loop to go through and check to see if
    each number is in order, but again, is there a simpler way to check?

    Thanks in advance.
    TJ
    --
    Posted via http://www.ruby-forum.com/.
     
    Trent Jones, Dec 1, 2008
    #1
    1. Advertising

  2. > G'day all, I'm new to Ruby, been studying Software Engineering at
    > university and they have been teaching in Java.
    >
    > As such, I'm trying to learn as few of the basics by going through and
    > comverting smoe of the programs I made into Ruby. At the moment, I'm
    > struggling a bit with the control structures, if-then-else is fine,
    > switch/case is fine. I'm just a little confused about the for and
    > while/dowhile loops.
    >
    > I'm trying to make a "infinite monkeys" simulation, i.e. initiate an
    > array of 'x' length and then fill it with random numbers, then check to
    > see if those numbers are in order, if not, repeat the process. More or
    > less anyway.
    >
    > At the moment I'm using this loop to fill the array:
    > for num in (0..Integer(a))
    > monkey[num]=Integer(rand*5+1)
    > end
    > variable 'a' is input by the user to determine how big a sequence, i.e.
    > 5 numbers in a row.
    >
    > Is this the easiest way of doing things?
    > And then I could use a similar loop to go through and check to see if
    > each number is in order, but again, is there a simpler way to check?
    >
    > Thanks in advance.
    > TJ
    > --
    > Posted via http://www.ruby-forum.com/.


    monkey = []
    a = gets

    begin
    0.upto(a.to_i) do |num|
    monkey.push((rand*5+1).to_i)
    end
    end while a.sort != a

    (Of course it is not the most time- and memory- effective way...)

    Jakub Pavlik
    --
    Zatímco velbloud dvouhrbý má hrby dva, Dromedár má jen jeden.
     
    Jakub Pavlík jn., Dec 1, 2008
    #2
    1. Advertising

  3. Trent Jones

    Jorrel Guest

    > 0.upto(a.to_i) do |num|
    > monkey.push((rand*5+1).to_i)
    > end


    or, since you're not using num anyway:
    a.to_i.times { monkey.push((rand*5+1).to_i)


    --
    jorrel
     
    Jorrel, Dec 1, 2008
    #3
  4. Hi Jakub,

    What would be the quickest way of doing it? (in terms of time and =
    memory?)

    Thanks,
    Dan

    -----Original Message-----
    From: Jakub Pavl=EDk jn. [mailto:]=20
    Sent: 01 December 2008 11:53
    To: ruby-talk ML
    Subject: Re: Control Structures

    > G'day all, I'm new to Ruby, been studying Software Engineering at
    > university and they have been teaching in Java.
    >=20
    > As such, I'm trying to learn as few of the basics by going through and
    > comverting smoe of the programs I made into Ruby. At the moment, I'm
    > struggling a bit with the control structures, if-then-else is fine,
    > switch/case is fine. I'm just a little confused about the for and
    > while/dowhile loops.
    >=20
    > I'm trying to make a "infinite monkeys" simulation, i.e. initiate an
    > array of 'x' length and then fill it with random numbers, then check =

    to
    > see if those numbers are in order, if not, repeat the process. More or
    > less anyway.
    >=20
    > At the moment I'm using this loop to fill the array:
    > for num in (0..Integer(a))
    > monkey[num]=3DInteger(rand*5+1)
    > end
    > variable 'a' is input by the user to determine how big a sequence, =

    i.e.
    > 5 numbers in a row.
    >=20
    > Is this the easiest way of doing things?
    > And then I could use a similar loop to go through and check to see if
    > each number is in order, but again, is there a simpler way to check?
    >=20
    > Thanks in advance.
    > TJ
    > --=20
    > Posted via http://www.ruby-forum.com/.


    monkey =3D []
    a =3D gets

    begin
    0.upto(a.to_i) do |num|
    monkey.push((rand*5+1).to_i)
    end
    end while a.sort !=3D a

    (Of course it is not the most time- and memory- effective way...)

    Jakub Pavlik
    --=20
    Zat=EDmco velbloud dvouhrb=FD m=E1 hrby dva, Dromed=E1r m=E1 jen jeden.
     
    Daniel Malcolm Webb [dbw], Dec 1, 2008
    #4
  5. Trent Jones

    prasad Guest

    [Note: parts of this message were removed to make it a legal post.]

    See if this satisfies you:

    while (arr = Array.new(4){rand 4}) != [0,1,2,4]
    p arr
    end
    p arr

    best wishes,
    Prasad


    On Mon, Dec 1, 2008 at 5:07 PM, Trent Jones <> wrote:

    > G'day all, I'm new to Ruby, been studying Software Engineering at
    > university and they have been teaching in Java.
    >
    > As such, I'm trying to learn as few of the basics by going through and
    > comverting smoe of the programs I made into Ruby. At the moment, I'm
    > struggling a bit with the control structures, if-then-else is fine,
    > switch/case is fine. I'm just a little confused about the for and
    > while/dowhile loops.
    >
    > I'm trying to make a "infinite monkeys" simulation, i.e. initiate an
    > array of 'x' length and then fill it with random numbers, then check to
    > see if those numbers are in order, if not, repeat the process. More or
    > less anyway.
    >
    > At the moment I'm using this loop to fill the array:
    > for num in (0..Integer(a))
    > monkey[num]=Integer(rand*5+1)
    > end
    > variable 'a' is input by the user to determine how big a sequence, i.e.
    > 5 numbers in a row.
    >
    > Is this the easiest way of doing things?
    > And then I could use a similar loop to go through and check to see if
    > each number is in order, but again, is there a simpler way to check?
    >
    > Thanks in advance.
    > TJ
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >
     
    prasad, Dec 1, 2008
    #5
  6. Trent Jones

    prasad Guest

    [Note: parts of this message were removed to make it a legal post.]

    sorry error: first line should be

    while (arr = Array.new(4){rand 4}) != [0,1,2,3]

    Prasad



    On Mon, Dec 1, 2008 at 6:08 PM, prasad <> wrote:

    > See if this satisfies you:
    >
    > while (arr = Array.new(4){rand 4}) != [0,1,2,4]
    > p arr
    > end
    > p arr
    >
    > best wishes,
    > Prasad
    >
    >
    >
    > On Mon, Dec 1, 2008 at 5:07 PM, Trent Jones <> wrote:
    >
    >> G'day all, I'm new to Ruby, been studying Software Engineering at
    >> university and they have been teaching in Java.
    >>
    >> As such, I'm trying to learn as few of the basics by going through and
    >> comverting smoe of the programs I made into Ruby. At the moment, I'm
    >> struggling a bit with the control structures, if-then-else is fine,
    >> switch/case is fine. I'm just a little confused about the for and
    >> while/dowhile loops.
    >>
    >> I'm trying to make a "infinite monkeys" simulation, i.e. initiate an
    >> array of 'x' length and then fill it with random numbers, then check to
    >> see if those numbers are in order, if not, repeat the process. More or
    >> less anyway.
    >>
    >> At the moment I'm using this loop to fill the array:
    >> for num in (0..Integer(a))
    >> monkey[num]=Integer(rand*5+1)
    >> end
    >> variable 'a' is input by the user to determine how big a sequence, i.e.
    >> 5 numbers in a row.
    >>
    >> Is this the easiest way of doing things?
    >> And then I could use a similar loop to go through and check to see if
    >> each number is in order, but again, is there a simpler way to check?
    >>
    >> Thanks in advance.
    >> TJ
    >> --
    >> Posted via http://www.ruby-forum.com/.
    >>
    >>

    >
     
    prasad, Dec 1, 2008
    #6
  7. > Hi Jakub,
    >
    > What would be the quickest way of doing it? (in terms of time and memory?)
    >
    > Thanks,
    > Dan
    >
    > -----Original Message-----
    > From: Jakub Pavlík jn. [mailto:]
    > Sent: 01 December 2008 11:53
    > To: ruby-talk ML
    > Subject: Re: Control Structures
    >
    > > G'day all, I'm new to Ruby, been studying Software Engineering at
    > > university and they have been teaching in Java.
    > >
    > > As such, I'm trying to learn as few of the basics by going through and
    > > comverting smoe of the programs I made into Ruby. At the moment, I'm
    > > struggling a bit with the control structures, if-then-else is fine,
    > > switch/case is fine. I'm just a little confused about the for and
    > > while/dowhile loops.
    > >
    > > I'm trying to make a "infinite monkeys" simulation, i.e. initiate an
    > > array of 'x' length and then fill it with random numbers, then check to
    > > see if those numbers are in order, if not, repeat the process. More or
    > > less anyway.
    > >
    > > At the moment I'm using this loop to fill the array:
    > > for num in (0..Integer(a))
    > > monkey[num]=Integer(rand*5+1)
    > > end
    > > variable 'a' is input by the user to determine how big a sequence, i.e.
    > > 5 numbers in a row.
    > >
    > > Is this the easiest way of doing things?
    > > And then I could use a similar loop to go through and check to see if
    > > each number is in order, but again, is there a simpler way to check?
    > >
    > > Thanks in advance.
    > > TJ
    > > --
    > > Posted via http://www.ruby-forum.com/.

    >
    > monkey = []
    > a = gets
    >
    > begin
    > 0.upto(a.to_i) do |num|
    > monkey.push((rand*5+1).to_i)
    > end
    > end while a.sort != a
    >
    > (Of course it is not the most time- and memory- effective way...)
    >
    > Jakub Pavlik
    > --
    > Zatímco velbloud dvouhrbý má hrby dva, Dromedár má jen jeden.
    >
    >


    The following version doesn't use Array#sort (which returns sorted copy of Array; I haven't looked at Ruby source which sorting algorithm is used, you can look yourself if you want), but I presume that you don't need complete set of a numbers in every attempt. However it isn't hard to make another version without this presumption.

    a = gets.to_i

    loop do
    ok = true

    monkey = []

    a.times do
    n = (rand*5+1).to_i
    if monkey.empty? || n >= monkey.last then
    monkey.push n
    else
    ok = false
    break
    end
    end

    puts monkey.join(',')

    break if ok
    end
     
    Jakub Pavlík jn., Dec 1, 2008
    #7
  8. Like many languages, there are lots of ways to do things. Using a block
    with Array.new lets you initialise an Array with n elements in one go,
    where the block is invoked n times to create each element.

    I think that comparing monkey == monkey.sort is the easiest way to check
    for values in sequence, but a more esoteric way is using
    Enumerable#each_cons to check each pair in turn.

    So this gives the following solution:

    require 'enumerator'
    puts "How many elements?"
    a = Integer(gets)

    loop do
    monkey = Array.new(a) { rand(a) }
    out_of_order = false
    monkey.each_cons(2) { |x,y|
    if x > y
    out_of_order = true
    break
    end
    }
    puts "#{monkey.inspect}, out_of_order=#{out_of_order}"
    end

    Now, you can squeeze this a bit more, because each_cons normally returns
    nil, but break can pass a different return value. This gives:

    loop do
    monkey = Array.new(a) { rand(a) }
    out_of_order = monkey.each_cons(2) { |x,y|
    break true if x > y
    }
    puts "#{monkey.inspect}, out_of_order=#{out_of_order ? "yes" : "no"}"
    end

    Now, to get really funky. The Enumerable module has a bunch of methods
    for operating on sequences of objects which are yielded by the 'each'
    method. Using to_enum you can insert a proxy object which maps the call
    to #each to a call to another method - such as #each_cons. So then you
    get:

    loop do
    monkey = Array.new(a) { rand(a) }
    out_of_order = monkey.to_enum:)each_cons,2).find { |x,y| x > y }
    puts "#{monkey.inspect} #{out_of_order && "bad monkey!"}"
    end

    I certainly wouldn't have written that as a newcomer to Ruby :) But
    it's nice to know that, when you have mastered the basics, there's lots
    more to chew on.

    Regards,

    Brian.

    P.S. Try all this stuff in irb. For example, to try out each_cons:

    irb(main):001:0> require 'enumerator'
    => true
    irb(main):002:0> [1,2,3,4,5].each_cons(2) { |x| p x }
    [1, 2]
    [2, 3]
    [3, 4]
    [4, 5]
    => nil
    --
    Posted via http://www.ruby-forum.com/.
     
    Brian Candler, Dec 1, 2008
    #8
  9. Trent Jones

    Robert Dober Guest

    I am not sure if you want this optimization

    a = 3
    m = a.times.inject([]){ |r,| x=rand(a); x < (r.last||0) && break; r <<
    x } until m
    or if you prefer
    m = a.pred.times.inject( [rand( a )]){ |r,| x=rand(a); x < r.last &&
    break; r << x } until m

    now apart of not creating the full array when it is already unsorted
    it is also a brain teaser to work all those new methods out, but that
    is the beauty of Ruby.

    P.S Ruby 1.8.7 needed works with PL 72 and 1.9 of course.

    Cheers
    Robert
     
    Robert Dober, Dec 1, 2008
    #9
  10. Robert Dober wrote:
    > I am not sure if you want this optimization


    Whilst this demonstrates Dober's Law that every program can be written
    in the form of an inject statement, it doesn't necessarily mean that's
    the best thing to do in every case :)
    --
    Posted via http://www.ruby-forum.com/.
     
    Brian Candler, Dec 1, 2008
    #10
  11. Trent Jones

    Robert Dober Guest

    On Mon, Dec 1, 2008 at 7:26 PM, Brian Candler <> wrote:
    > Robert Dober wrote:
    >> I am not sure if you want this optimization

    >
    > Whilst this demonstrates Dober's Law that every program can be written

    You know I have to jump at any opportunity to present inject when
    Robert (K) has not done that yet.
    > in the form of an inject statement, it doesn't necessarily mean that's
    > the best thing to do in every case :)

    The rest is a question of taste ...
    Cheers
    Robert
     
    Robert Dober, Dec 1, 2008
    #11
  12. Trent Jones

    Trent Jones Guest

    Thanks to everyone for the help, I manage to get it working, not at all
    optimised like some of the code here, but it was more to get a hang of
    control structures and a few other things in ruby.
    --
    Posted via http://www.ruby-forum.com/.
     
    Trent Jones, Dec 6, 2008
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. varala_kanth
    Replies:
    3
    Views:
    466
    varala_kanth
    Jun 20, 2004
  2. M. Duijkers
    Replies:
    2
    Views:
    479
    Joe Smith
    Dec 12, 2004
  3. tweak
    Replies:
    14
    Views:
    2,789
    Eric Sosman
    Jun 11, 2004
  4. Shawn
    Replies:
    13
    Views:
    476
    Thomas Hawtin
    Oct 21, 2006
  5. Alfonso Morra
    Replies:
    11
    Views:
    722
    Emmanuel Delahaye
    Sep 24, 2005
Loading...

Share This Page