SitePoint Sponsor

User Tag List

Results 1 to 7 of 7

Thread: for loops (101)

Hybrid View

  1. #1
    SitePoint Zealot superjacent's Avatar
    Join Date
    Jun 2007
    Location
    Melbourne, Australia.
    Posts
    121
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    for loops (101)

    In learning Ruby I've dug out some old C++ exercises and one in particular which can be found here deals with a for loop. I'm basically converting the C++ code to Ruby code. I won't repeat the C++ code but the exercise is as follows:

    Write a C++ program that asks the user to enter a number of rows to be printed. It should then display for the first row one asterisk preceded by periods. The second row should display two asterisks preceded by periods and so on until all the rows have been printed as entered by the user.

    A sample run would be like so:

    Code:
    Enter number of rows: 5
    ....*
    ...**
    ..***
    .****
    *****
    It seemed to take me ages to get my head around the structure of for loops and I ended up firstly using while loops just to get the program working. After that I eventually got this for loop version working.

    Code:
    # nestedforloop.rb
    # 19 Apr, 2009.
    print "Enter the number of rows: "
    rows = gets.chomp!
    rows = rows.to_i
    
    for r in (1..rows)
      for c in (1..(rows - r))
        print "."
      end
      r == rows ? c = 1 : c += 1
      for c in (c..rows)
        print "*"
      end
      print "\n"
    end
    The above works but I'm thinking maybe there was a way I didn't need to use the r == rows ? c = 1 : c += 1 line, as that wasn't necessary under the C++ for loop/code. Should I stop thinking in terms of how traditional for loops are structured? I'm led to believe that for is in fact an alias (if that's the right word) of the each method. Any hints re - using the each method would be appreciated (as applied to the above).

  2. #2
    SitePoint Evangelist
    Join Date
    Feb 2006
    Location
    Worcs. UK
    Posts
    404
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    for is an alias of each.

    Code:
    for a in b
      # do stuff
    end
    Is the equivalent of
    Code:
    b.each do |a|
      #do stuff
    end
    for .. in is in the original pickaxe book and can be read here:

    http://www.ruby-doc.org/docs/Program...ssions.html#UK

  3. #3
    SitePoint Zealot superjacent's Avatar
    Join Date
    Jun 2007
    Location
    Melbourne, Australia.
    Posts
    121
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks Reggie. I transposed my for loop example to the each way of doing things and it wouldn't run, initially. The program kept stalling on the r == rows ? c = 1 : c += 1 line. Finally I determined it was a scoping issue for the c variable. Initializing the c variable prior to the looping solved the problem. Is probably easier showing the code in full.

    Code:
    print "Enter the number of rows: "
    rows = gets.chomp!
    rows = rows.to_i
    
    c = 1 # had to initialize here re - scoping (could be any integer value)
    
    (1..rows).each do |r|
      (1..(rows - r)).each do |c|
        print "."
      end
    
      r == rows ? c = 1 : c += 1  # if c not initilized above, is out of scope here.
      
      (c..rows).each do |c|
        print "*"
      end
      print "\n"
    end
    I think I prefer the for method, even if it is an alias of each.

  4. #4
    SitePoint Enthusiast TomK32's Avatar
    Join Date
    Mar 2008
    Location
    Berchtesgaden, Germany
    Posts
    32
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    hehe, tricky one but I solved it by using (rows-r) instead of c:

    Code:
    for r in (1..rows)
      for c in (1..(rows - r))
        print "."
      end
      for c in ((rows - r)...rows)
        print "*"
      end
      print "\n"
    end
    just a geek trying to change the world
    I'm a ruby on rails developer in Vienna, Austria. My github.

  5. #5
    SitePoint Zealot superjacent's Avatar
    Join Date
    Jun 2007
    Location
    Melbourne, Australia.
    Posts
    121
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by TomK32 View Post
    hehe, tricky one but I solved it by using (rows-r) instead of c:

    Code:
    for r in (1..rows)
      for c in (1..(rows - r))
        print "."
      end
      for c in ((rows - r)...rows)
        print "*"
      end
      print "\n"
    end
    Thanks, very clever. I admit it took me a little while to figure out why it wasn't printing an extra column and then I noticed the three dots.

  6. #6
    SitePoint Member
    Join Date
    Apr 2009
    Location
    Australia
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here's another possible solution and an example of the expressiveness of Ruby.

    Code:
    print "Enter the number of rows: "
    rows = gets.strip.to_i
    
    rows.times do |row|
      print '.' * (rows-row-1)
      print '*' * (row+1)
      puts ''
    end

  7. #7
    SitePoint Zealot superjacent's Avatar
    Join Date
    Jun 2007
    Location
    Melbourne, Australia.
    Posts
    121
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by alexpooley View Post
    Here's another possible solution and an example of the expressiveness of Ruby.

    Code:
    print "Enter the number of rows: "
    rows = gets.strip.to_i
    
    rows.times do |row|
      print '.' * (rows-row-1)
      print '*' * (row+1)
      puts ''
    end
    Thanks Alex, very clever. I've just spent the last 10 minutes going over the times method, learning that the count starts from zero and hence your rows-row-1 line. Also the print '.' * number is very useful.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •