Thread: Harvard CS50 Online Help -- Mario Pyramid

  1. #1
    Registered User
    Join Date
    Jan 2016
    Posts
    13

    Harvard CS50 Online Help -- Mario Pyramid

    Hey all!

    So I'm taking the Harvard CS50 course online in my free time to help me learn some coding / computer logic. I've worked through some of the problems in Problem Set 1, but am stuck on the Mario Pyramid example. For those unfamiliar with it, here's the prompt:

    Write, in a file called mario.c in your ~/workspace/pset1 directory, a program that recreates this half-pyramid using hashes (#) for blocks. However, to make things more interesting, first prompt the user for the half-pyramid’s height, a non-negative integer no greater than 23. (The height of the half-pyramid pictured above happens to be 8.) If the user fails to provide a non-negative integer no greater than 23, you should re-prompt for the same again. Then, generate (with the help of printf and one or more loops) the desired half-pyramid. Take care to align the bottom-left corner of your half-pyramid with the left-hand edge of your terminal window, as in the sample output below, wherein underlined text represents some user’s input.

    username@ide50:~/workspace/pset1 $ ./mario
    height: 8
    ##
    ###
    ####
    #####
    ######
    #######
    ########
    #########

    Note that the rightmost two columns of blocks must be of the same height. No need to generate the pipe, clouds, numbers, text, or Mario himself.


    Now, I can get user input and make sure it is within the correct range (below 23 but greater than 0), but I am having a lot of trouble with the following:


    • Working out the logic behind printing the correct number of spaces and hash marks. I can (obviously) figure out how the number of spaces/hash marks is related to each individual row, but not one formula to apply to every row (if that makes sense). This is obviously something I need to (and want to) work out on my own, but if someone could give me the best way to start, that'd be great.
    • Figuring out the print process for printing multiple lines of text (hashes and spaces), each containing a different arrangement of characters based on the logic in the first bullet point.
    • Probably related to the above bullet point, but I am really unsure of where to define my "rows" variable. If the user inputs "4" as the height, for example, there would be 4 rows (and five columns). But the logic behind the variables, aside from one for a hashmark and one for a space, is really frustrating me.

    Here is the shell of code that I have right now. At the moment it is only telling the user whether or not his or her input is within the correct range, so I don't know if it's helpful.

    Code:
    #include <stdio.h>
    #include <string.h>
    
    
    int main(void)
        {
            int height;
            int block;
            int space;
            int rows;
            
             printf("Please input a height value for this half-pyramid.\n");
            scanf("%i", &height);
            
            if (height < 23 || height > 0)
                {
                    printf("The value %i a valid height. \n", height);
    
    
            
    
    
                }
            else if (height > 23 || height < 0)
                {
                     printf("The value %i an invalid height.\n", height);
    
    
                }
    
    
            
                
            return 0 ;
        }
    Thanks in advance, guys!


  2. #2
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    The description of the problem says the height should be "no greater than 23," meaning that 23 is an allowed height. Your code, as written, does not handle the case in which the user enters 23 as the height.
    You don't need an else-if to handle the invalid height. It can simply be else.
    Your if condition also fails to enforce any constraints at all. Literally all real numbers are less than 23 OR greater than zero.
    The problem contradicts itself. It shows an example of what it should look like, but that example is in opposition to later, when it says "the rightmost two columns of blocks must be of the same height," unless the forum is eating whitespace, destroying the correct formatting, which is entirely possible.

    You don't need a "formula" to apply to all rows. You can use a for loop, which is responsible for the rows, with two other for loops inside it, one for drawing the spaces, and the other for drawing blocks.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  3. #3
    Registered User
    Join Date
    Jun 2011
    Posts
    4,508
    Another way that the input validation requirements are not being met in the code you posted:

    >> If the user fails to provide a non-negative integer no greater than 23, you should re-prompt for the same again.

  4. #4
    Registered User
    Join Date
    Jan 2016
    Posts
    13
    Quote Originally Posted by Elkvis View Post
    The description of the problem says the height should be "no greater than 23," meaning that 23 is an allowed height. Your code, as written, does not handle the case in which the user enters 23 as the height.
    You don't need an else-if to handle the invalid height. It can simply be else.
    Your if condition also fails to enforce any constraints at all. Literally all real numbers are less than 23 OR greater than zero.
    The problem contradicts itself. It shows an example of what it should look like, but that example is in opposition to later, when it says "the rightmost two columns of blocks must be of the same height," unless the forum is eating whitespace, destroying the correct formatting, which is entirely possible.

    You don't need a "formula" to apply to all rows. You can use a for loop, which is responsible for the rows, with two other for loops inside it, one for drawing the spaces, and the other for drawing blocks.
    Thanks for the reply, Elkvis!

    Thanks for catching the mistake with the range of my condition--and I'm not sure why I put ||, I actually meant &&.

    The forum messed with the formatting--in the code, the stairs of the pyramid will start lowest on the left and get higher as it moves right (it's reversed there, it would seem). But the intended point was that the top of the pyramid would not be one # but two ##. So the right-most column would be the same height as the one to its left.

    As for the rows-maybe this is my being new to coding, but I'm just confused about defining the "rows". I know that the code would be something like ...

    Code:
    for(rows=0, rows < height, rows++)
    But don't I need to define rows somewhere as referring to the the number of lines being printed? Right now, I only have "rows" defined as an integer, and have it initialized to 0 in the for() function. Where exactly is it supposed to be defined as the number of lines being printed?


    Sorry if that is a dumb question.

  5. #5
    Registered User
    Join Date
    Jan 2016
    Posts
    13
    Quote Originally Posted by Matticus View Post
    Another way that the input validation requirements are not being met in the code you posted:

    >> If the user fails to provide a non-negative integer no greater than 23, you should re-prompt for the same again.
    Thanks for the reply! This is actually something I've had trouble figuring out. The cs50 class provides its own library with premade functions that are "training wheels," of sorts. I've used those functions for the most part, but in this case, their GetInt() function has that re-prompt built in. I've been wracking my brain for a while now to figure out how to get a loop to go back to the beginning of the loop if certain parameters are not met.

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    So the pyramid of height 8 should look like this:

    Code:
    .
           ##
          ###
         ####
        #####
       ######
      #######
     ########
    #########
    Correct? (Ignore the period. It's required to get the board to format it correctly.)

    Quote Originally Posted by mcavanaugh8 View Post
    But don't I need to define rows somewhere as referring to the the number of lines being printed? Right now, I only have "rows" defined as an integer, and have it initialized to 0 in the for() function. Where exactly is it supposed to be defined as the number of lines being printed?
    You don't need to do that with your "rows" variable. It literally exists as the counter for the loop. Height holds the number of lines being printed.
    Last edited by Elkvis; 02-01-2016 at 01:07 PM.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  7. #7
    Registered User
    Join Date
    Jun 2011
    Posts
    4,508
    Quote Originally Posted by mcavanaugh8 View Post
    Thanks for the reply! This is actually something I've had trouble figuring out. The cs50 class provides its own library with premade functions that are "training wheels," of sorts. I've used those functions for the most part, but in this case, their GetInt() function has that re-prompt built in. I've been wracking my brain for a while now to figure out how to get a loop to go back to the beginning of the loop if certain parameters are not met.
    You apparently know how "if()" statements work:

    Code:
    if( /* expression is true */ )
        // do this
    A loop (for instance, the "while()") works in a similar way:

    Code:
    while( /* expression is true */ )
        // loop this
    For input, I'd suggest a "do-while" loop, as the loop is guaranteed to run at least once (allowing values to be entered) before checking the condition.

    The implementation of "GetInt()" shouldn't matter, as long as it gives you the value entered by the user. The "invalid input" message can be separate from the prompt in the "GetInt()" function.



    I feel like two people giving advice about two separate things simultaneously might be confusing. I'd suggest focusing on what Elkvis is helping with, as that pertains more to program planning (which should come first).

  8. #8
    Registered User
    Join Date
    Jan 2016
    Posts
    13
    Quote Originally Posted by Elkvis View Post
    So the pyramid of height 8 should look like this:

    Code:
    .
           ##
          ###
         ####
        #####
       ######
      #######
     ########
    #########
    Correct? (Ignore the period. It's required to get the board to format it correctly.)



    You don't need to do that with your "rows" variable. It literally exists as the counter for the loop. Height holds the number of lines being printed.
    Yup, that is the correct formatting for the pyramid.

    And ohh, that makes sense now--thanks! I think I've also figured out that the number of spaces is equal to height - rows, so I think some progress has been made there. But the nested for loops will probably take me some time to figure out.

  9. #9
    Registered User
    Join Date
    Jan 2016
    Posts
    13
    Quote Originally Posted by Matticus View Post
    You apparently know how "if()" statements work:

    Code:
    if( /* expression is true */ )
        // do this
    A loop (for instance, the "while()") works in a similar way:

    Code:
    while( /* expression is true */ )
        // loop this
    For input, I'd suggest a "do-while" loop, as the loop is guaranteed to run at least once (allowing values to be entered) before checking the condition.

    The implementation of "GetInt()" shouldn't matter, as long as it gives you the value entered by the user. The "invalid input" message can be separate from the prompt in the "GetInt()" function.



    I feel like two people giving advice about two separate things simultaneously might be confusing. I'd suggest focusing on what Elkvis is helping with, as that pertains more to program planning (which should come first).
    I believe I was simply over-thinking the whole thing, assuming for some reason that I needed some kind of function that returned you to the start, rather than just using an if / else or while loop. Thanks! And you're right. I'm going to focus on the program planning and then get down to the grittier stuff.

  10. #10
    Registered User
    Join Date
    Jan 2016
    Posts
    13
    Do you know why my compiler might tell me to put a semicolon at the end of my for() statement but when I add the semicolon, it asks me to take it away? This is incredibly frustrating lol.

  11. #11
    Registered User
    Join Date
    Jun 2011
    Posts
    4,508
    You should post the exact error message, along with a simplified yet complete program that exhibits that error message. Also tell us what compiler you are using.

  12. #12
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Post your latest code.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  13. #13
    Registered User
    Join Date
    Jan 2016
    Posts
    13
    I'm using the CS50 IDE for the course. My code is as follows:

    Code:
    #include <stdio.h>
    #include <string.h>
    
    
    int main(void)
        {
            int height;
            int blocks;
            int space;
            int rows;
            
            printf("Please input a height value for this half-pyramid.\n");
            scanf("%i", &height);
            
            for(height <= 23 && height > 0);
                {
                    printf("The value %i a valid height. Printing...\n", height);
                    
                    for(rows = 0, rows < height, rows++);
                        {
                            printf("\n");
                    
                    
                            for(blocks = height, blocks = height + 1, blocks++);
                                {
                                    printf("#");
                                }
                        }
                }
                
            for(height > 23 && height < 0); 
                {
                    printf("The value %i an invalid height.\n", height);
                }
    
    
                
            return 0 ;
        }
    And I get the following errors:

    mario_test.c:14:39: error: expected ';' in 'for' statement specifier
    for(height <= 23 && height > 0);
    ^
    mario_test.c:14:39: error: expected ';' in 'for' statement specifier
    mario_test.c:14:26: error: expression result unused [-Werror,-Wunused-value]
    for(height <= 23 && height > 0);
    ~~~~~~~~~~~~ ^ ~~~~~~~~~~
    mario_test.c:18:36: error: expression result unused [-Werror,-Wunused-value]
    for(rows = 0, rows < height, rows++);
    ~~~~ ^ ~~~~~~
    mario_test.c:18:52: error: expected ';' in 'for' statement specifier
    for(rows = 0, rows < height, rows++);
    ^
    mario_test.c:18:52: error: expected ';' in 'for' statement specifier
    mario_test.c:23:75: error: expected ';' in 'for' statement specifier
    for(blocks = height, blocks = height + 1, blocks++);
    ^
    mario_test.c:23:75: error: expected ';' in 'for' statement specifier
    mario_test.c:23:76: error: for loop has empty body [-Werror,-Wempty-body]
    for(blocks = height, blocks = height + 1, blocks++);
    ^
    mario_test.c:23:76: note: put the semicolon on a separate line to silence this warning
    mario_test.c:18:53: error: for loop has empty body [-Werror,-Wempty-body]
    for(rows = 0, rows < height, rows++);
    ^
    mario_test.c:18:53: note: put the semicolon on a separate line to silence this warning
    mario_test.c:30:38: error: expected ';' in 'for' statement specifier
    for(height > 23 && height < 0);
    ^
    mario_test.c:30:38: error: expected ';' in 'for' statement specifier
    mario_test.c:30:25: error: expression result unused [-Werror,-Wunused-value]
    for(height > 23 && height < 0);
    ~~~~~~~~~~~ ^ ~~~~~~~~~~
    mario_test.c:14:40: error: for loop has empty body [-Werror,-Wempty-body]
    for(height <= 23 && height > 0);
    ^
    mario_test.c:14:40: note: put the semicolon on a separate line to silence this warning
    mario_test.c:30:39: error: for loop has empty body [-Werror,-Wempty-body]
    for(height > 23 && height < 0);
    ^
    mario_test.c:30:39: note: put the semicolon on a separate line to silence this warning
    If I take them away, I get:

    mario_test.c:14:39: error: expected ';' in 'for' statement specifier
    for(height <= 23 && height > 0)
    ^
    mario_test.c:14:39: error: expected ';' in 'for' statement specifier
    mario_test.c:18:36: error: expression result unused [-Werror,-Wunused-value]
    for(rows = 0, rows < height, rows++)
    ~~~~ ^ ~~~~~~
    mario_test.c:18:52: error: expected ';' in 'for' statement specifier
    for(rows = 0, rows < height, rows++)
    ^
    mario_test.c:18:52: error: expected ';' in 'for' statement specifier
    mario_test.c:23:75: error: expected ';' in 'for' statement specifier
    for(blocks = height, blocks = height + 1, blocks++)
    ^
    mario_test.c:23:75: error: expected ';' in 'for' statement specifier
    mario_test.c:14:26: error: expression result unused [-Werror,-Wunused-value]
    for(height <= 23 && height > 0)
    ~~~~~~~~~~~~ ^ ~~~~~~~~~~
    mario_test.c:30:38: error: expected ';' in 'for' statement specifier
    for(height > 23 && height < 0);
    ^
    mario_test.c:30:38: error: expected ';' in 'for' statement specifier
    mario_test.c:30:25: error: expression result unused [-Werror,-Wunused-value]
    for(height > 23 && height < 0);
    ~~~~~~~~~~~ ^ ~~~~~~~~~~
    mario_test.c:30:39: error: for loop has empty body [-Werror,-Wempty-body]
    for(height > 23 && height < 0);
    ^
    mario_test.c:30:39: note: put the semicolon on a separate line to silence this warning

    Thanks to both of you again, by the way.

  14. #14
    Registered User
    Join Date
    May 2010
    Posts
    4,596
    Look closely at that "for" loop:
    Code:
            for(height > 23 && height < 0);
    That is not how a for() loop is formatted (with or without the semicolon). Perhaps you meant for this to be an if() statement?

    Edit: also look closely at the error message:
    mario_test.c:14:39: error: expected ';' in 'for' statement specifier
    for(height <= 23 && height > 0)
    I suggest you review your documentation for for(;;) loops and if() statements.

    Jim
    Last edited by jimblumberg; 02-01-2016 at 02:36 PM.

  15. #15
    Registered User
    Join Date
    Jun 2011
    Posts
    4,508
    In addition to Jim's comments, look at the body of the second "for()" loop. It only prints a message. If this loop is entered, you give it no chance to stop. That would be a good place to prompt for a new value...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Mario (Hash) Pyramid aligned to the right?
    By petey615 in forum C Programming
    Replies: 8
    Last Post: 01-03-2013, 01:38 AM
  2. Code for CS50 functions?
    By VEN0M in forum C Programming
    Replies: 19
    Last Post: 07-25-2012, 11:53 AM
  3. Plz help me to include cs50.h and cs50.c into Code::Block
    By Huncowboy in forum C Programming
    Replies: 4
    Last Post: 03-09-2010, 10:05 AM
  4. I just applied to Harvard University
    By Terrance in forum A Brief History of Cprogramming.com
    Replies: 10
    Last Post: 07-06-2003, 04:18 PM