Program Planning For Patterns

Example: Problem pat10.c

Upside Down Triangle Get number of rows from the user. Say that user enters 6 for then number of rows. Then print the triangle
******
 *****
  ****
   ***
    **
     *
The first thing we must do is ask and get from the user the number of rows he/she wants. So the following code belongs at the beginning of main:
int numRows;
printf("Please enter the number of rows you want.\n");
scanf("%d", &num);
  1. Rule: print single characters
  2. Concept: Next Print Position

  3. The function printf does two things: it prints and it sets up the next print position. When it prints a non-newline, non-tab character the next print position is directly to the right of the character just printed. When printf prints a newline, the next print position is down one line all the way to the left of the screen.
  4. Put another way function printf prints from left to right until it prints a newline which moves the print position down one line and to the left of the screen.
  5. Scan a line of the triangle above. from left to right. For instance look at the third line from the top. The first thing to notice is that the asterisks do not start at the left. On the left it looks like there is nothing before the first asterisk. BUT if there were truly nothing there, the asterisks would start all the way to the left. So there is something there: some spaces.
  6. OBSERVATION: So from left to right, the third line is some spaces followed by some asterisks followed by a newline which sets up the start of the next line.

  7. Important: All lines of the pattern follow this observation. Even the first line which starts with zero spaces, then some asterisks, then a newline.
  8. Now a bit of the plan that prints a row in the triangle.
    repeat:
      print  ' '
    repeat:
      print  '*'
    print '\n'
    
    Code like this is fake code. It is not the C language; it just helps us with the planning. The offical name for this is pseudo-code.
  9. Now let's add in variables that control how many repetitions:
    repeat numSpc copies:
      print  ' '
    repeat numAst copies:
      print  '*'
    print '\n'
    //prepare for the next row.
    numSpc++
    numAst--
    
    The last two lines are because each row has one more space than the row before it and one fewer asterisk.
  10. Because we want to print several rows we take the pseudo-code above and "nest" it inside a loop that repeats it numRows times.
    repeat numRows copies:
      repeat numSpc copies:
        print  ' '
      repeat numAst copies:
        print  '*'
      print '\n'
      //prepare for the next row.
      numSpc++
      numAst--
    
  11. Now we initialize numSpc and numAst. That is give them their values for the first row.
    int numSpc = 0;
    int numAst = numRows;
    repeat numRows copies:
      repeat numSpc copies:
        print  ' '
      repeat numAst copies:
        print  '*'
      print '\n'
      //prepare for the next row.
      numSpc++
      numAst--
    
  12. Now we translate into C:
    int numSpc = 0;
    int numAst = numRows;
    int i=0;
    while (i<numRows) {
      int j=0;   //new row; no spaces printed yet
      while (j<numSpc) {
        printf(" ");
        j++;   //one more space printed in current row
      }
      int k=0; //no asterisks printed yet
      while (k<numAst) {
        printf("*");
        k++; //one more asterisk printed in current row
      }
      printf("\n");
      //prepare for the next row.
      numSpc++;
      numAst--;
      //one more row has been printed:
      i++;
    }
    
    This code should be put into main() { } after the scanf.
  13. Using for loops instead of while loops:
    int numSpc = 0;
    int numAst = numRows;
    int i, j, k;
    for(i=0; i<numRows; i++) {
      for(j=0; j<numSpc; j++)
        printf(" ");
      for(k=0; k<numAst; k++)
        printf("*");
      printf("\n");
      //prepare for the next row.
      numSpc++;
      numAst--;
    }