3.10.5. pyramid.cpp

Time: 00:06:27 | Download: Large Small | Streaming

A computer program expresses a solution (not all solutions, just one) to a given problem. You must solve the problem before you can write the program! Problem-solving is a learned skill. You learn and develop problem-solving skills through experience. Furthermore, you learn to draw pictures and use them to help solve problems through extensive practice. The picture bridges the problem and a program that solves it. The pyramid example demonstrates how programmers use pictures to help solve a problem.

The Problem

                   X
                  XXX
                 XXXXX
                XXXXXXX
               XXXXXXXXX
              XXXXXXXXXXX
             XXXXXXXXXXXXX
            XXXXXXXXXXXXXXX
           XXXXXXXXXXXXXXXXX
          XXXXXXXXXXXXXXXXXXX
         XXXXXXXXXXXXXXXXXXXXX
        XXXXXXXXXXXXXXXXXXXXXXX
       XXXXXXXXXXXXXXXXXXXXXXXXX
      XXXXXXXXXXXXXXXXXXXXXXXXXXX
     XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
   XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The pyramid problem. Draw a pyramid of X's twenty lines high on the console. Make the program flexible so we can easily change the number of rows in the pyramid. The previous discussion of for-loops suggested that data has a "shape" and that we can use one for-loop for each dimension to process the data. When programs send organized data to the console, they must begin in the upper left corner and work left to right and top to bottom. So, our first thought is that we have one dimension running from the top of the pyramid to the bottom and one from the left edge to the right. However, although it's not immediately obvious, the pyramid problem involves three dimensions. We can more easily identify the dimensions with a picture.

The Solution

Computer scientists use many tools to help solve problems. The following solution uses two of the most common tools: pictures and patterns. Drawing the entire pyramid is unnecessary; the first few rows should be enough to generalize the solution successfully. A picture representing a problem helps a computer scientist solve the problem in at least four different ways:

  1. provides a visualization of the problem that forms a bridge between the problem and an eventual program; a given program is just one of many possible expressions of the problem solution
  2. identifies and organizes the information that the computer scientist has
  3. makes it easier to see and generalize patterns appearing in the problem (i.e., the relationships between the known bits of information)
  4. highlights any missing information
HEIGHT
A symbolic constant for the total pyramid height; change the value of the constant to change the pyramid's height easily. We could also make the height a variable, and, following well-established naming conventions, we would change the spelling to height
level
The pyramid level (or line or row) the program is filling with X's (first dimension)
spaces
The problem's solution requires the program to move the cursor from the left edge of the console to the location of the first X. The program moves the cursor by printing spaces or blanks (made visible in the picture with boxes). The variable spaces is the number of spaces needed to move the cursor (second dimension)
xes
the number of X's needed to fill the current level or row of the pyramid (third dimension)
Picture Relationships
The top four levels of the pyramid of X's labeled with the program variables.
level spaces xes
0 3 1
1 2 3
2 1 5
3 0 7
General HEIGHT - level - 1 2 * level + 1
Problem solving with pictures. It isn't necessary to include the entire problem in the picture. We can identify the relationships between HEIGHT, level, spaces, and xes from the top four levels. The variable level is the independent variable: it doesn't depend on other variables. As the level increases, the number of spaces on each row of the pyramid decreases by 1, and the number of Xs increases by 2. This observation implies that spaces and xes are each a function of level (they are dependent variables): spaces = f(level) and xes = g(level).

Subtraction and division cause the dependent variable to decrease as the independent variable increases - a constant decrease by 1 suggests subtraction. Alternatively, addition and multiplication cause the dependent variable to increase with the independent variable - increasing at a constant rate of 2 suggests multiplication by 2. However, there is a problem: xes is always odd and 2 × odd = even and 2 × even = even. We solve this problem by adding 1. With some trial and error, we discover:

The key to translating the solution above into the code below is recognizing that the for-loops are just counting characters. The formulas in the table and the picture represent how many characters the program should print - how many times each loop should iterate or repeat.

Program Solution

#define HEIGHT 20								// (a)
#include <iostream>
using namespace std;

int main()
{
	for (int level = 0; level < HEIGHT; level++)				// (b)
	{
		for (int spaces = 0; spaces < HEIGHT - level - 1; spaces++)	// (c)
			cout << ' ';
		for (int xes = 0; xes < 2 * level + 1; xes++)			// (d)
			cout << 'X';
		cout << endl;							// (e)
	}
	
	return 0;
}
Nested for-loops: pyramid.cpp. The loop-control variables of both inner or nested loops depend on the value of the outer loop.
  1. A symbolic constant denoting the pyramid's height; we can also use const int height = 20; or enum { HEIGHT = 20 }; (chap 5).
  2. Iterates through the levels from the top of the pyramid to the bottom.
  3. Moves the cursor from the left edge of the console to the left edge of the pyramid by printing the space character. The program must print multiple spaces, so the cout statement must be in a loop.
  4. Prints the Xs forming the pyramid. Printing an X moves the cursor to the right one space. The program must print multiple Xs, so the cout statement must be in a loop.
  5. After printing the last X, ending a level, cout prints an endl, dropping the cursor down one line and moving it to the left edge of the console.
Don't needlessly force code into loops. If an operation only runs once, it doesn't need to be in a loop. I've witnessed students concoct for-loops with complex expressions that always run once. Such loops are confusing, inefficient, and amateurish. The pyramid solution only needs one new line at the end of each level, so cout << endl; must be in the outer loop but not in a nested loop.