Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C++ (http://www.go4expert.com/forums/cpp/)
-   -   Triangle of Digits - Clipping the end of the Triangle (http://www.go4expert.com/forums/triangle-digits-clipping-triangle-t19850/)

Towely 22Oct2009 08:03

Triangle of Digits - Clipping the end of the Triangle
 
I'm attempting to create a computer program that prints a triangle of digits, as well as a "ruler" that measures the user specified width of the screen, showing the width in digits. The ruler must have a tens row and a ones row.
The program reads three integers:
a) the screen width (maximum 80)
b) the width of the triangle.
c) the position of the 1 column of the triangle, relative to the left margin.
The '1' column of the triangle must be printed at the given position on the screen. If the screen width is not wide enough to fit the entire triangle, the triangle must be clipped. In the extreme case, if the position is greater than the screen width, nothing is drawn (the entire triangle is clipped).
Here's a couple examples of what the output should look like:
(Sorry about the code tags, it's the only way I could show the correct spacing)
Example one:
Code:

Enter screen width: 20
Enter triangle width: 4
Enter position: 7
        1        2
12345678901234567890
      1234
      123
      12
      1

Example two:
Enter screen width: 10
Enter triangle width: 4
Enter position: 8
Code:

        1
1234567890
      123
      123
      12
      1

I've gotten the triangle and ruler to print correctly, and I've figured out how to properly put spaces before the triangle.
My problem is with the code for Clipping the end of the triangle off. For some reason, my program stops printing the triangle two columns early.
Why does it stop printing 2 lines early?
Here's what the output looks like, followed by my code. Any quick help would be appreciated.
Code:

Enter Screen Width: 30
Enter Triangle Width: 20
Enter Position: 21
        1        2        3
123456789012345678901234567890
                    12345678
                    12345678
                    12345678
                    12345678
                    12345678
                    12345678
                    12345678
                    12345678
                    12345678
                    12345678
                    12345678
                    12345678
                    12345678
                    1234567
                    123456
                    12345
                    1234
                    123
                    12
                    1

So there you can see that it stops printing two lines early.
Here's my code, where am I going wrong?
Code:

#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
  int screenWidth, triWidth, position;
  cout << "Enter Screen Width: ";
  cin >> screenWidth;
  cout << "Enter Triangle Width: ";
  cin >> triWidth;
  cout << "Enter Position: ";
  cin >> position;
  int ruler = (screenWidth / 10);
  for (int topRuler = 1; topRuler <= ruler; topRuler++)
  {
      cout << "        " << topRuler; // Prints the 1st ruler                                             
  }
  cout << endl;
  int showNextRuler;
  for (int nextRuler = 1; nextRuler <= screenWidth; nextRuler++)
  {
      int showNextRuler = (nextRuler % 10);
      cout << showNextRuler;  // Prints the 2nd ruler                                                     
  }
  cout << endl;
  cout << endl;
  for (int i = triWidth; i >= 1; i--)
  {
      for (int y = 1; y < position; y++)
      {
        cout.put (' '); // Prints spaces before the triangle                                             
      }
      for (int triangle = 1; triangle <= i && (triangle + position) <= screenWidth; triangle++)
      {
        int showTriangle;
        showTriangle = (triangle % 10);
            if (triangle + position >= screenWidth)
            {
              break; // Clips the Triangle - Why does it begin clipping 2 spaces early?
            }
            else
            {
              cout << showTriangle;
            }
      }
      cout << endl;
  }
}


xpi0t0s 22Oct2009 15:25

Re: Triangle of Digits - Clipping the end of the Triangle
 
The problem here is that you're thinking from 1 instead of from 0. In C the first of anything is numbered zero. This shows in your incorrect ruler; the left-hand column is zero, not 1, and if the screen is 30 characters wide then the right hand column is column 29 not 30.

So both triangle and position are 1-based, and this is why your triangle is clipped 2 characters early. One fix is to add a fudge factor of 2 to screenWidth: "for (int triangle = 1; triangle < i && (triangle + position) <= screenWidth+2; triangle++)" and "if (triangle + position >= screenWidth+2)"; another (harder but better) solution is to modify the code so that the first of anything is counted as zero instead of 1.

If anything needs numbering from 1 for the user's convenience, then work internally with zero-based numbering and convert between 1-based and 0-based at input/output, rather than trying to work with 1-based variables in the code. After 28 years of programming this is my conclusion having spent countless hours trying to make code work by adding +1 and -1 fudge factors all over the place.

So for example screenWidth of 30 is fine as is, just count x from 0-29 (and display x+1, thus performing the conversion back to 1-based at output); triWidth=20 is also OK and count from 0-19. position=21 from the user's point of view so this is 20 from the programmer's point of view. Keep position as 21 if you like and remember it's a 1-based number (which means you have to add a -1 fudge every time you use it), or deduct 1 after input (converting it to 0-based at input) so you don't have to remember and can just use it as is.


All times are GMT +5.5. The time now is 05:55.