Triangle of Digits - Clipping the end of the Triangle

Discussion in 'C++' started by Towely, Oct 22, 2009.

  1. Towely

    Towely New Member

    Joined:
    Oct 22, 2009
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    0
    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)
                {
                  [COLOR=red] break; // Clips the Triangle - Why does it begin clipping 2 spaces early? [/COLOR]
                }
                else
                {
                   cout << showTriangle;
                }
          }
          cout << endl;
       }
    }
    
     
  2. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    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.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice