DIAMOND SHAPE

Discussion in 'C++' started by coinjo, Nov 10, 2005.

  1. coinjo

    coinjo Guest

    I need to write a program which takes a number as an input and prints a
    diamond of # and $. The number of rows in the shape is equal to the
    number entered by the user. Your program should display the shape for
    both even and odd value of size. For example if user enters number 7
    the program should print following shape.


    #
    #$#
    #$#$#
    #$#$#$#
    #$#$#
    #$#
    #



    If user enters a value 6, the program prints diamond in following
    shape.

    #
    #$#
    #$#$#
    #$#$#
    #$#
    #

    I have tried very hard and this is the best i could come up with

    #include<iostream>
    using namespace std;

    int main()
    {

    int rows=0;
    cout<<"Enter the number of rows of the diamond"<<endl;
    cin>>rows;

    int space=0;
    int space1=0;
    int space2=0;
    int space3=0;
    int space4=1;
    int a=0;
    int b=0;


    space1=rows/2;
    space2=space1;
    space3=space1;
    a=rows-2;
    space=space1+a;

    int count=0;
    int count1=0;
    int count2=0;
    int count3=0;
    int count4=0;
    int count5=0;
    int count6=0;

    int char1=1;
    int char2=0;

    b=a-1;


    char2=space1+b;

    while(count1<space1)
    {

    count2=0;
    count3=0;

    while(count2<space2)
    {

    cout<<" ";
    count2=count2+1;

    }

    while(count3<char1)
    {

    cout<<"#";
    count3=count3+1;

    if(count3<char1)

    {

    cout<<"$";
    count3=count3+1;

    }
    }

    cout<<endl;
    count1=count1+1;
    char1=char1+2;
    space2=space2-1;

    }


    while(count<=space)
    {
    cout<<"#";
    count=count+1;
    if(count<space)
    {
    cout<<"$";
    count=count+1;
    }
    }

    cout<<endl;

    while(count4<=space3)
    {

    count5=0;
    count6=0;

    while(count5<space4)
    {

    cout<<" ";
    count5=count5+1;

    }

    while(count6<char2)
    {

    cout<<"#";
    count6=count6+1;


    if(count6<char2)
    {

    cout<<"$";
    count6=count6+1;

    }
    }

    space4=space4+1;
    char2=char2-2;
    count4=count4+1;
    cout<<endl;
    }
    }

    This above code works fine for 3 but not for other odd values like 5
    and 7. Can anyone help?
    Also how to make it work for even numbers?
    coinjo, Nov 10, 2005
    #1
    1. Advertising

  2. coinjo

    coinjo Guest

    I need to write a program which takes a number as an input and prints a
    diamond of # and $. The number of rows in the shape is equal to the
    number entered by the user. My program should display the shape for
    both even and odd value of size. For example if user enters number 7
    the program should print following shape.

    #
    #$#
    #$#$#
    #$#$#$#
    #$#$#
    #$#
    #

    If user enters a value 6, the program prints diamond in following
    shape.

    #
    #$#
    #$#$#
    #$#$#
    #$#
    #

    I have tried very hard and this is the best i could come up with

    #include<iostream>
    using namespace std;

    int main()
    {

    int rows=0;
    cout<<"Enter the number of rows of the diamond"<<endl;
    cin>>rows;

    int space=0;
    int space1=0;
    int space2=0;
    int space3=0;
    int space4=1;
    int a=0;
    int b=0;

    space1=rows/2;
    space2=space1;
    space3=space1;
    a=rows-2;
    space=space1+a;

    int count=0;
    int count1=0;
    int count2=0;
    int count3=0;
    int count4=0;
    int count5=0;
    int count6=0;

    int char1=1;
    int char2=0;

    b=a-1;

    char2=space1+b;

    while(count1<space1)
    {

    count2=0;
    count3=0;

    while(count2<space2)
    {

    cout<<" ";
    count2=count2+1;

    }

    while(count3<char1)
    {

    cout<<"#";
    count3=count3+1;

    if(count3<char1)

    {

    cout<<"$";
    count3=count3+1;

    }
    }

    cout<<endl;
    count1=count1+1;
    char1=char1+2;
    space2=space2-1;

    }

    while(count<=space)
    {
    cout<<"#";
    count=count+1;
    if(count<space)
    {
    cout<<"$";
    count=count+1;

    }
    }

    cout<<endl;

    while(count4<=space3)
    {

    count5=0;
    count6=0;

    while(count5<space4)
    {

    cout<<" ";
    count5=count5+1;

    }

    while(count6<char2)
    {

    cout<<"#";
    count6=count6+1;

    if(count6<char2)
    {

    cout<<"$";
    count6=count6+1;

    }
    }

    space4=space4+1;
    char2=char2-2;
    count4=count4+1;
    cout<<endl;

    }
    }

    This above code works fine for 3 but not for other odd values like 5
    and 7. Can anyone help?
    Also how to make it work for even numbers?
    coinjo, Nov 10, 2005
    #2
    1. Advertising

  3. coinjo

    coinjo Guest

    I need to write a program which takes a number as an input and prints a
    diamond of # and $. The number of rows in the shape is equal to the
    number entered by the user. My program should display the shape for
    both even and odd value of size. For example if user enters number 7
    the program should print following shape.

    #
    #$#
    #$#$#
    #$#$#$#
    #$#$#
    #$#
    #

    If user enters a value 6, the program prints diamond in following
    shape.

    #
    #$#
    #$#$#
    #$#$#
    #$#
    #

    I have tried very hard and this is the best i could come up with

    #include<iostream>
    using namespace std;

    int main()
    {

    int rows=0;
    cout<<"Enter the number of rows of the diamond"<<endl;
    cin>>rows;

    int space=0;
    int space1=0;
    int space2=0;
    int space3=0;
    int space4=1;
    int a=0;
    int b=0;

    space1=rows/2;
    space2=space1;
    space3=space1;
    a=rows-2;
    space=space1+a;

    int count=0;
    int count1=0;
    int count2=0;
    int count3=0;
    int count4=0;
    int count5=0;
    int count6=0;

    int char1=1;
    int char2=0;

    b=a-1;

    char2=space1+b;

    while(count1<space1)
    {

    count2=0;
    count3=0;

    while(count2<space2)
    {

    cout<<" ";
    count2=count2+1;

    }

    while(count3<char1)
    {

    cout<<"#";
    count3=count3+1;

    if(count3<char1)

    {

    cout<<"$";
    count3=count3+1;

    }
    }

    cout<<endl;
    count1=count1+1;
    char1=char1+2;
    space2=space2-1;

    }

    while(count<=space)
    {
    cout<<"#";
    count=count+1;
    if(count<space)
    {
    cout<<"$";
    count=count+1;

    }
    }

    cout<<endl;

    while(count4<=space3)
    {

    count5=0;
    count6=0;

    while(count5<space4)
    {

    cout<<" ";
    count5=count5+1;

    }

    while(count6<char2)
    {

    cout<<"#";
    count6=count6+1;

    if(count6<char2)
    {

    cout<<"$";
    count6=count6+1;

    }
    }

    space4=space4+1;
    char2=char2-2;
    count4=count4+1;
    cout<<endl;

    }
    }

    This above code works fine for 3 but not for other odd values like 5
    and 7. Can anyone help?
    Also how to make it work for even numbers?
    coinjo, Nov 10, 2005
    #3
  4. On 10 Nov 2005 08:44:45 -0800, "coinjo" <> wrote:

    >I need to write a program which takes a number as an input and prints a
    >diamond of # and $. The number of rows in the shape is equal to the


    *snip*

    >
    >This above code works fine for 3 but not for other odd values like 5
    >and 7. Can anyone help?
    >Also how to make it work for even numbers?


    I've been learning C++ for 3 days. This is what I came up with. I
    would like for experienced programmers to critique my code so that I
    can learn, please:

    #include <iostream>
    #include <math>
    #include <vector>

    // prints a row of diamonds
    void PrintRow(const int numRows, const int lengthRow, bool
    switchStartCharacter = false)
    {
    std::string rowCharacters = "#$";

    // figure out offset (to 'center' row)
    int lineOffset = (numRows - lengthRow) / 2;

    int currentCharacter = 0;

    if( switchStartCharacter )
    ++ currentCharacter;

    // shift by offset
    for(int i = 0; i < lineOffset; i++)
    std::cout << " ";

    // print row
    for(int i = 0; i < lengthRow; ++ i)
    std::cout << rowCharacters[(currentCharacter
    ++)%2];

    std::cout << std::endl;
    }

    int PrintDiamond(const int numRows)
    {
    // it doesn't make sense to have rows less than 1
    if( numRows < 1 )
    return -1;

    // create a vector containing the number of entries
    // for each row in half a diamond
    std::vector<int> halfDiamond;

    // store a variable reminding us if diamond is even
    bool isEven = numRows % 2 == 0;

    // calculate half the diamond
    for(int currentRow = 1; currentRow <= ceil(numRows / 2.0f); ++
    currentRow)
    halfDiamond.push_back(currentRow*2 - 1);

    // print out the top half of the diamond
    for(int currentRow = 0; currentRow < halfDiamond.size(); ++
    currentRow)
    PrintRow(numRows, halfDiamond[currentRow]);

    // if even, repeat the middle row
    if( isEven )
    PrintRow(numRows, halfDiamond[halfDiamond.size()-1],
    isEven);

    // print out the bottom half of the diamond
    for(int currentRow = halfDiamond.size() - 2; currentRow >= 0;
    -- currentRow)
    PrintRow(numRows, halfDiamond[currentRow], isEven);

    return 0;
    }

    int main()
    {
    int rowCount;

    std::cout << "How many rows in the diamond?" << std::endl;
    std::cin >> rowCount;
    std::cout << std::endl;

    // action
    return PrintDiamond(rowCount);
    }
    Jim Kafka Ninte, Nov 10, 2005
    #4
  5. coinjo

    W Marsh Guest

    On Thu, 10 Nov 2005 20:56:00 +0000, Jim Kafka Ninte <> wrote:

    >On 10 Nov 2005 08:44:45 -0800, "coinjo" <> wrote:
    >
    >>I need to write a program which takes a number as an input and prints a
    >>diamond of # and $. The number of rows in the shape is equal to the

    >
    >*snip*
    >
    >>
    >>This above code works fine for 3 but not for other odd values like 5
    >>and 7. Can anyone help?
    >>Also how to make it work for even numbers?

    >
    >I've been learning C++ for 3 days. This is what I came up with. I
    >would like for experienced programmers to critique my code so that I
    >can learn, please:


    Here's that code again without choppy line lengths (sorry):

    #include <iostream>
    #include <math>
    #include <vector>

    // prints a row of diamonds
    void PrintRow(const int numRows, const int lengthRow, bool switchStartCharacter = false)
    {
    std::string rowCharacters = "#$";

    // figure out offset (to 'center' row)
    int lineOffset = (numRows - lengthRow) / 2;

    int currentCharacter = 0;

    if( switchStartCharacter )
    ++ currentCharacter;

    // shift by offset
    for(int i = 0; i < lineOffset; i++)
    std::cout << " ";

    // print row
    for(int i = 0; i < lengthRow; ++ i)
    std::cout << rowCharacters[(currentCharacter ++)%2];

    std::cout << std::endl;
    }

    int PrintDiamond(const int numRows)
    {
    // it doesn't make sense to have rows less than 1
    if( numRows < 1 )
    return -1;

    // create a vector containing the number of entries
    // for each row in half a diamond
    std::vector<int> halfDiamond;

    // store a variable reminding us if diamond is even
    bool isEven = numRows % 2 == 0;

    // calculate half the diamond
    for(int currentRow = 1; currentRow <= ceil(numRows / 2.0f); ++ currentRow)
    halfDiamond.push_back(currentRow*2 - 1);

    // print out the top half of the diamond
    for(int currentRow = 0; currentRow < halfDiamond.size(); ++ currentRow)
    PrintRow(numRows, halfDiamond[currentRow]);

    // if even, repeat the middle row
    if( isEven )
    PrintRow(numRows, halfDiamond[halfDiamond.size()-1], isEven);

    // print out the bottom half of the diamond
    for(int currentRow = halfDiamond.size() - 2; currentRow >= 0; -- currentRow)
    PrintRow(numRows, halfDiamond[currentRow], isEven);

    return 0;
    }

    int main()
    {
    int rowCount;

    std::cout << "How many rows in the diamond?" << std::endl;
    std::cin >> rowCount;
    std::cout << std::endl;

    // action
    return PrintDiamond(rowCount);
    }
    W Marsh, Nov 10, 2005
    #5
  6. On Thu, 10 Nov 2005 20:56:00 +0000, Jim Kafka Ninte <>
    wrote:

    >On 10 Nov 2005 08:44:45 -0800, "coinjo" <> wrote:
    >
    >>I need to write a program which takes a number as an input and prints a
    >>diamond of # and $. The number of rows in the shape is equal to the

    >
    >*snip*
    >
    >>
    >>This above code works fine for 3 but not for other odd values like 5
    >>and 7. Can anyone help?
    >>Also how to make it work for even numbers?

    >
    >I've been learning C++ for 3 days. This is what I came up with. I
    >would like for experienced programmers to critique my code so that I
    >can learn, please:


    I must say ... after only three days of learning C++, you have
    presented us with a program that not only compiles cleanly, with only
    1 warning, on Borland C++ Builder v. 5 ... and runs correctly! And
    your comments are also just enough to be useful. And I like your
    variable names which are self-documenting.

    My hat is off to you, sir! Many who post uncompileable, untested, and
    obfuscated code here (including myself, from time to time) can learn
    from your example.

    Nevertheless, there are a few things worth considering, and I have
    written my suggestions "inline":

    >#include <iostream>
    >#include <math>
    >#include <vector>


    You don't have to #include <math> for this ... works OK without it.

    >// prints a row of diamonds
    >void PrintRow(const int numRows, const int lengthRow, bool
    >switchStartCharacter = false)


    The "const" for the arguments, which you pass by value, have no effect
    on the caller; they are only constant within the scope of PrintRow().
    IOW, you cannot change the value passed by the caller anyway, so you
    might want to drop the "const" qualifiers here. But some people like
    to document the "constness" of the arguments within the function, so
    it is really a matter of taste. It's not wrong, in any case.

    Also, "numRows" and "lengthRow" should be unsigned IMHO because it
    discourages users of PrintRow() from passing scurrilous negative
    values. Besides, it would get rid of that nasty warning at line 50
    <g>.

    >{
    > std::string rowCharacters = "#$";
    >
    > // figure out offset (to 'center' row)
    > int lineOffset = (numRows - lengthRow) / 2;
    >
    > int currentCharacter = 0;
    >
    > if( switchStartCharacter )
    > ++ currentCharacter;
    >
    > // shift by offset
    > for(int i = 0; i < lineOffset; i++)
    > std::cout << " ";
    >
    > // print row
    > for(int i = 0; i < lengthRow; ++ i)
    > std::cout << rowCharacters[(currentCharacter
    >++)%2];
    >
    > std::cout << std::endl;
    >}
    >
    >int PrintDiamond(const int numRows)


    Same comments regarding const and unsigned as above...

    >{
    > // it doesn't make sense to have rows less than 1
    > if( numRows < 1 )
    > return -1;


    This is unnecessary if your argument "numRows" is unsigned ... you
    might also (or instead of) want to check for a maximum value here.

    You also return the value returned from PrintDiamond() in your main()
    function. Now I know this is "air code", and as such we shouldn't try
    to bust a gut trying to implement custom exception classes for
    something like this, etc. ... but the "-1" has some problems.

    First of all, your program should only return something other than 0
    from main() if it hasn't run properly to completion (for whatever
    reason ... out of memory error, etc.). Here, it would come merely as
    the result of invalid user input. IMHO you should fail more gracefully
    here and perhaps give the user a second chance. Of course, this
    complicates the code a bit, because you would have to perform sanity
    checking on the input (which you don't). Then again, this is only "air
    code"...

    Secondly, -1 is what most people would consider a "magic number". That
    has nothing to do with the value -1, but with the fact that you have
    hard-coded this number into your code without any documentation as to
    what it means. Most programmers would provide a constant here which
    would be defined in some other place, either as a static const
    variable in your .cpp file, in a header file, or as an "extern"
    variable. The name of the constant should indicate something about the
    error condition here. Other potential errors would have different
    values, e.g.:

    static const int ERROR_INVALID_INPUT = -1;
    // have to catch std::bad_alloc for this one:
    static const int ERROR_OUT_OF_MEMORY = -2;

    Thirdly, if your argument is unsigned, you needn't return anything at
    all from this function. The exceptional case would be if the argument
    passed were too big, in which case you would usually have two choices:

    (a) substitute the value with some predetermined maximum, and perhaps
    notify the caller with a message, and continue processing;
    (b) throw a C++ exception which you could catch in main() by
    surrounding the function call in a try{} block. In the catch{}
    statement block, you could output an error message, log the error to
    some other device or file, and (optionally) return some value from
    main() != 0.

    > // create a vector containing the number of entries
    > // for each row in half a diamond
    > std::vector<int> halfDiamond;
    >
    > // store a variable reminding us if diamond is even
    > bool isEven = numRows % 2 == 0;


    Shorter and, IMHO, more readable:

    bool isEven = !(numRows % 2);

    There is an implicit conversion from int to bool here, but that is OK
    since bool is also an integral type in C++ ... You might consider
    making this a stand-alone function if you see it being used a lot.

    > // calculate half the diamond
    > for(int currentRow = 1; currentRow <= ceil(numRows / 2.0f); ++
    >currentRow)
    > halfDiamond.push_back(currentRow*2 - 1);
    >
    > // print out the top half of the diamond
    > for(int currentRow = 0; currentRow < halfDiamond.size(); ++
    >currentRow)


    Here is where the warning appears: you compare a signed type
    (currentRow) with the return value from std::vector<int>::size(),
    which returns an unsigned integral type (99% of the time it is
    unsigned int, but it really depends on your implementation's
    definition of std::vector::size_type).

    > PrintRow(numRows, halfDiamond[currentRow]);
    >
    > // if even, repeat the middle row
    > if( isEven )
    > PrintRow(numRows, halfDiamond[halfDiamond.size()-1],
    >isEven);
    >
    > // print out the bottom half of the diamond
    > for(int currentRow = halfDiamond.size() - 2; currentRow >= 0;
    >-- currentRow)
    > PrintRow(numRows, halfDiamond[currentRow], isEven);
    >
    > return 0;
    >}
    >
    >int main()
    >{
    > int rowCount;
    >
    > std::cout << "How many rows in the diamond?" << std::endl;
    > std::cin >> rowCount;
    > std::cout << std::endl;
    >
    > // action
    > return PrintDiamond(rowCount);
    >}


    --
    Bob Hairgrove
    Bob Hairgrove, Nov 10, 2005
    #6
  7. coinjo

    coinjo Guest

    I am not allowed to use vectors in this program.
    coinjo, Nov 11, 2005
    #7
  8. coinjo

    Guest

    coinjo wrote:
    > I am not allowed to use vectors in this program.


    Don't wait for a complete piece of code you can hand in.

    Neil etc. have given you more than enough help to restructure your code
    and come up with a good algorithm. Use your brain now and don't wait
    for a verbatum solution.

    Report back with what you came up with.

    Cheers,
    Andre
    , Nov 11, 2005
    #8
  9. coinjo wrote:
    >
    > I am not allowed to use vectors in this program.


    You don't need to.
    If you look at Jim's code you will notice, that he used
    that vector only to cache the individual lines.

    Just do the calculations 2 times (in opposite order) and
    your diamond should be perfect.

    --
    Karl Heinz Buchegger
    Karl Heinz Buchegger, Nov 11, 2005
    #9
  10. coinjo

    Guest

    Bob Hairgrove wrote:
    > On Thu, 10 Nov 2005 20:56:00 +0000, Jim Kafka Ninte <>
    > wrote:
    >
    >
    > Also, "numRows" and "lengthRow" should be unsigned IMHO because it
    > discourages users of PrintRow() from passing scurrilous negative
    > values. Besides, it would get rid of that nasty warning at line 50
    > <g>.
    >
    > --
    > Bob Hairgrove
    >


    And since we are influencing a newbie here, or just to keep balance to
    the force, or something like that, I'll speak for those wishing to
    abolish unsigned numbers:

    Basically, IMO, they should only be used for bit-flags, not for
    numbers. Without starting a religious flamewar, let's just leave it by
    noting exactly that - it is a bit of a religious arguement. If you (ie
    the OP) have only been programming for 3 days, I suggest trying both
    (and mostly doing whatever a supervisor or coding standard says,
    if/when employed as a programmer) and then waiting until you have years
    of experience before making a decision :). It might come down to
    which way gets you 'burnt' more. I've been burnt more by negative
    numbers. I've yet to be burnt by numbers that are 'too big' (unless
    they are negative turned to unsigned).

    That for me is the essense of it - I don't know what 'too big' is. I
    used to think images with dimensions greater than 16K or 32K were too
    big, but they aren't any more. 'What is 'too big' today, won't be
    tomorrow, and I want my code to last for years - I have 15 year old
    code still in use today. For me, 'too big' is typically if the
    allocation failed. If I had to test for 'too big' I'd test for as big
    as possible without looking negative :). Which means I should just
    check for negative. Maybe it depends on what kind of code you are
    writing - ie for me it is usually image processing code.

    Ah, but I didn't mean to argue it. I see the value of unsigned: It
    tries to express the 'reality' of what your code is modeling, which is
    a good thing - for example, images can't have negative widths, so why
    allow it (in the prototype) only to disallow it with a check? If
    compilers made implicit signed/unsigned conversions an error instead of
    a warning, I would probably use unsigned properly. etc etc. Google the
    groups for 'religion signed unsigned' or something like that to see the
    arguments, or wait until you are old and cynical like us...

    P.S. yeah, passing in 'const int x' to a function bugs me too, but
    again, some have their reasons (i have yet to understand them, whereas
    I find both sides of signed/unsigned easy to understand). If anything,
    I could see 'const int & x', which also seems silly, but at least it is
    consistent with 'const Foo & x', which is good practice if Foo is a
    large object...

    Tony
    , Nov 11, 2005
    #10
  11. On 11 Nov 2005 14:38:59 -0800, wrote:

    >That for me is the essense of it - I don't know what 'too big' is.


    In the case we have here of printing out a diamond on the console
    screen, I would say that any number larger than the width of the
    screen in characters is probably too big.

    --
    Bob Hairgrove
    Bob Hairgrove, Nov 12, 2005
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jay Dean
    Replies:
    57
    Views:
    26,175
    Arne Vajhøj
    Dec 10, 2013
  2. Alexander Stippler

    virtual inheritance / dreaded diamond problem

    Alexander Stippler, Jul 14, 2003, in forum: C++
    Replies:
    0
    Views:
    1,867
    Alexander Stippler
    Jul 14, 2003
  3. coinjo

    DIAMOND SHAPE

    coinjo, Nov 10, 2005, in forum: C++
    Replies:
    11
    Views:
    1,142
    Old Wolf
    Nov 11, 2005
  4. amit
    Replies:
    4
    Views:
    2,367
    Juha Nieminen
    Nov 25, 2008
  5. Replies:
    8
    Views:
    354
    John Stephens
    Sep 8, 2013
Loading...

Share This Page