1

This is the flag that I have to get at the end:

*******************
**       *       **
* *      *      * *
*  *     *     *  *
*   *    *    *   *
*    *   *   *    *
*     *  *  *     *
*      * * *      *
*       ***       *
*******************
*       ***       *
*      * * *      *
*     *  *  *     *
*    *   *   *    *
*   *    *    *   *
*  *     *     *  *
* *      *      * *
**       *       **
*******************

I know how to do full star triangles but when it's empty on the inside I have no idea about how to proceed. Can anyone help me?

I tried and I just know how to do full star triangles and a star square/rectangle empty on the inside here is the code:

int main(void)
{
    int i, j, length, width;

    cout << "Length of rectangle? ";
    cin >> length;
    cout << endl;

    cout << "Width of rectangle? ";
    cin >> width;
    cout << endl;

    for ( i = 0; i < length; i++ )
        cout << "*";

    cout << endl;

    for ( i = 1; i < width - 1; i++ )
    {
        cout << "*";

        for ( j = 1; j < length - 1; j++ )
        {
            cout << " ";
        }

        cout << "*";
        cout << endl;
    }

    for ( i = 0; i < length; i++)
        cout << "*";

    cout << endl;

    return 0;
}
Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
  • 2
    Please note that your code would be much easier to read (both for yourself and for other people) if you used [indentation](https://en.wikipedia.org/wiki/Indentation_style). I have added it for you. – Andreas Wenzel Jun 01 '23 at 18:35
  • 3
    At what equalities do you need to write a star (think things like x ==y, x==width/2) etc. use that as a basis for your program (since you have to write line by line) – Pepijn Kramer Jun 01 '23 at 18:36
  • An easy way is to use a 2D array. You first fill it (1 = star, 0 = no star) and then draw. This allows to process segment by segment, including diagonals. Are you allowed to use such an array ? – Damien Jun 01 '23 at 18:54
  • unfortunately I am not allowed to use that – user 123456789 Jun 01 '23 at 18:59
  • In this case, you can use an helper function. Input are coordinates `i` and `j`, output is a boolean indicating if there is a star. Something like `return (i == 0) || (i == (n-1) || (i==j) || ... `. – Damien Jun 01 '23 at 19:02
  • I'm with Damien here. **Write functions** whenever possible. Break down your logic into smaller, more easily understood and *tested* pieces. – tadman Jun 01 '23 at 19:03
  • In your example output, the flag's height is identical to its width. How exactly is the flag supposed to look like if the flag's height is not equal to the flag's width? Or are you allowed to assume that the flag's height is always identical to its width? In that case, there is no point to ask for both values from the user. – Andreas Wenzel Jun 01 '23 at 20:46

5 Answers5

0

Getting the cross in the middle is easy:

if (i == ??? || j == ???)
    std::cout << '*';
else
    std::cout << ' ';

The diagnoals are slightly more tricky.

In your nested loop, print std::cout << (i+j) << '\t'. Do you see any pattern in the numbers that lets you identify one of the diagonals?

Then repeat the same thing with i-j. Do you see the pattern for the other diagonal?

In the end, your nested loop will look like this:

if (i == /*something*/ || j == /*something else*/ || i+j .../*some condition*/ || i-j .../*another condition*/)
    std::cout << '*';
else
    std::cout << ' ';
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
0

Lines 1, 10 and 19 are easy, as they each consist only of 19 *.

The problem is the lines 2 to 9 and 11 to 19.

However, do you notice a pattern in lines 2 to 9?

Line 2 consists of one *

  • followed by 0 spaces
  • followed by one *
  • followed by 7 spaces
  • followed by one *
  • followed by 7 spaces
  • followed by one *
  • followed by 0 spaces

followed by one *

Line 3 consists of one *

  • followed by 1 spaces
  • followed by one *
  • followed by 6 spaces
  • followed by one *
  • followed by 6 spaces
  • followed by one *
  • followed by 1 spaces

followed by one *.

Line 4 consists of one *

  • followed by 2 spaces
  • followed by one *
  • followed by 5 spaces
  • followed by one *
  • followed by 5 spaces
  • followed by one *
  • followed by 2 spaces

followed by one *.

Line 5 consists of one *

  • followed by 3 spaces
  • followed by one *
  • followed by 4 spaces
  • followed by one *
  • followed by 4 spaces
  • followed by one *
  • followed by 3 spaces

followed by one *.

Line 6 consists of one *

  • followed by 4 spaces
  • followed by one *
  • followed by 3 spaces
  • followed by one *
  • followed by 3 spaces
  • followed by one *
  • followed by 4 spaces

followed by one *.

Line 7 consists of one *

  • followed by 5 spaces
  • followed by one *
  • followed by 2 spaces
  • followed by one *
  • followed by 2 spaces
  • followed by one *
  • followed by 5 spaces

followed by one *.

Line 8 consists of one *

  • followed by 6 spaces
  • followed by one *
  • followed by 1 spaces
  • followed by one *
  • followed by 1 spaces
  • followed by one *
  • followed by 6 spaces

followed by one *.

Line 9 consists of one *

  • followed by 7 spaces
  • followed by one *
  • followed by 0 spaces
  • followed by one *
  • followed by 0 spaces
  • followed by one *
  • followed by 7 spaces

followed by one *.

The pattern is the following:

Assuming that size is the total size of the triangle (which is 19 in your case), then

line n consists of one *

  • followed by n-2 spaces
  • followed by one *
  • followed by (size/2) - n spaces
  • followed by one *
  • followed by (size/2) - n spaces
  • followed by one *
  • followed by n-2 spaces

followed by one *.

Note that in C, the result of 19 / 2 is 9, as the fractional part of the division is discarded.

Using this information about the pattern, you should be able to create a loop that in every loop iteration, prints one line as described above. That way, you should be able to solve the problem of printing the lines 2 to 9.

Printing the lines 11 to 19 should be easy afterwards, because these lines must only be printed in reverse order of the lines 2 to 9.

In accordance with the community guidelines for homework questions, I will not provide the full solution at this time. I can provide further information later, if necessary.

EDIT:

Since several other solutions have already been posted by other users, I will now also post my solution, which solves the problem as described above:

#include <iostream>

const int MAP_SIZE = 19;

static_assert( MAP_SIZE % 2 == 1, "MAP_SIZE must be odd" );

int main( void )
{
    //print first horizontal line
    for ( int i = 0; i < MAP_SIZE; i++ )
        std::cout << '*';
    std::cout << '\n';

    //print top half of flag
    for ( int i = 0; i < MAP_SIZE / 2 - 1; i++ )
    {
        std::cout << '*';
        for ( int j = 0; j < i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < MAP_SIZE/2 - 2 - i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < MAP_SIZE/2 - 2 - i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < i; j++ )
            std::cout << ' ';
        std::cout << '*';
        std::cout << '\n';
    }

    //print second horizontal line
    for ( int i = 0; i < MAP_SIZE; i++ )
        std::cout << '*';
    std::cout << '\n';

    //print bottom half of flag
    for ( int i = 0; i < MAP_SIZE / 2 - 1; i++ )
    {
        std::cout << '*';
        for ( int j = 0; j < MAP_SIZE/2 - 2 - i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < MAP_SIZE/2 - 2 - i; j++ )
            std::cout << ' ';
        std::cout << '*';
        std::cout << '\n';
    }

    //print third horizontal line
    for ( int i = 0; i < MAP_SIZE; i++ )
        std::cout << '*';
    std::cout << '\n';
}

However, I think that this problem is easier to solve using a 2D array (which you stated that you are not allowed to use). The 2D array is initialized to spaces and then the 3 horizontal, 3 vertical and 2 diagonal lines are drawn:

#include <iostream>

const int MAP_SIZE = 19;

static_assert( MAP_SIZE % 2 == 1, "MAP_SIZE must be odd" );

int main( void )
{
    char map[MAP_SIZE][MAP_SIZE];

    //initialize 2D array to spaces
    for ( int i = 0; i < MAP_SIZE; i++ )
        for ( int j = 0; j < MAP_SIZE; j++ )
            map[i][j] = ' ';

    //draw the 3 horizontal lines
    for ( int i = 0; i < MAP_SIZE; i++ )
    {
        map[         0][i] = '*';
        map[MAP_SIZE/2][i] = '*';
        map[MAP_SIZE-1][i] = '*';
    }

    //draw the 3 vertical lines
    for ( int i = 0; i < MAP_SIZE; i++ )
    {
        map[i][         0] = '*';
        map[i][MAP_SIZE/2] = '*';
        map[i][MAP_SIZE-1] = '*';
    }

    //draw the 2 diagonal lines
    for ( int i = 0; i < MAP_SIZE; i++ )
    {
        map[i][           i] = '*';
        map[i][MAP_SIZE-i-1] = '*';
    }

    //print the result
    for ( int i = 0; i < MAP_SIZE; i++ )
    {
        std::cout.write( map[i], MAP_SIZE );
        std::cout.put( '\n' );
    }
}
Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
  • Thank you so much since we are not allowed to use a 2d array I think what my teacher is waiting for as an answer is most definitely the first code you posted. – user 123456789 Jun 03 '23 at 08:58
0

Instead of calculating each line in a loop. Have a function return what to draw at each point. Then you can apply some basic algebra to decide if there's a point to draw.

#include <iostream>

char getPoint(int width, int height, int x, int y) {
    int xNorm = (x <= width / 2) ? x : (width - x);
    int yNorm = (y <= height / 2) ? y : (height - y);

    // borders
    if ( ((x == 0) || (x == (width)) || (y == 0) || (y == height)) ||  // borders
         ((x == width / 2) || (y == height / 2)) ||                    // middle stripe
         ((width >= height) && (yNorm == xNorm * height / width)) ||   // diagnols (when width >= height)
         ((height > width) && (xNorm == yNorm * width / height))       // diagnols (when height > width)
        )
    {
        return '*';
    }
    return ' ';
}

void printFlag(int width, int height) {
    for (int y = 0; y <= height; y++) {
        for (int x = 0; x <= width; x++) {
            std::cout << getPoint(width, height, x, y);
        }
        std::cout << std::endl;
    }
}

int main()
{
    int height = 18;
    int width = 18;
    printFlag(width, height);
    return 0;
}

The above prints:

*******************
**       *       **
* *      *      * *
*  *     *     *  *
*   *    *    *   *
*    *   *   *    *
*     *  *  *     *
*      * * *      *
*       ***       *
*******************
*       ***       *
*      * * *      *
*     *  *  *     *
*    *   *   *    *
*   *    *    *   *
*  *     *     *  *
* *      *      * *
**       *       **
*******************
selbie
  • 100,020
  • 15
  • 103
  • 173
0

Example (based on knowledge from 2D computer graphics course I had over 30 years ago). Using a 1D vector (dynamically allocated array) as memory buffer and the Bresenham's line algorithm

Live demo here : https://onlinegdb.com/Kg9HAdxfZ

#include <cassert>
#include <iostream>
#include <vector>

class Flag
{
public:
    Flag(int width, int height) :
        m_width{ width },
        m_height{ height },
        m_grid(width*height,false) // allocate buffer and clear to false
    {
        assert(width > 1);
        assert(height > 1);

        int w = width - 1;
        int h = height - 1;

        // outline of flag
        line(0, 0, w, 0);
        line(w, 0, w, h);
        line(w, h, 0, h);
        line(0, h, 0, 0);

        // diagonals
        line(0, 0, w, h);
        line(0, h, w, 0);

        // mid lines horizontal and vertical
        line(0, h / 2, w, h / 2);
        line(w / 2, 0, w / 2, h);
    };

    bool get(int x, int y) const
    {
        return m_grid.at(y * m_width + x);
    }

    int width() const noexcept
    {
        return m_width;
    }

    int height() const noexcept
    {
        return m_height;
    }

private:
    void set(int x, int y)
    {
        m_grid.at(y * m_width + x) = true;
    }

    // Bresenham's line algorithm 
    // https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
    void line(int x0, int y0, int x1, int y1)
    {
        int dx = abs(x1 - x0);;
        int sx = x0 < x1 ? 1 : -1;
        int dy = -abs(y1 - y0);
        int sy = y0 < y1 ? 1 : -1;
        int error = dx + dy;

        while (true)
        {
            set(x0, y0);
            if ((x0 == x1) && (y0 == y1)) break;

            int e2 = 2 * error;
            if (e2 >= dy)
            {
                if (x0 == x1) break;
                error = error + dy;
                x0 = x0 + sx;
            }
            if (e2 <= dx)
            {
                if (y0 == y1) break;
                error = error + dx;
                y0 = y0 + sy;
            }
        }
    }

private:
    int m_width;
    int m_height;
    
    // a buffer to hold true/false for each posision of the m_grid
    // think pixels ;)
    std::vector<bool> m_grid;
};

std::ostream& operator<<(std::ostream& os, const Flag& flag)
{
    for (int y = 0; y < flag.height(); ++y)
    {
        for (int x = 0; x < flag.width(); ++x)
        {
            if (flag.get(x, y))
            {
                os << "*";
            }
            else
            {
                os << " ";
            }
        }
        std::cout << "\n";
    }
    
    return os;
}

int main()
{
    Flag flag(47, 15);
    std::cout << flag;
    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19
-1
void DrawUKflag(int L, int W)
{

    for (int i = 0; i <=L; i++)
    {
        for (int k = 0; k <=W; k++) 
        {
            if (i==0||i==L/2||i==L ||k==0||k==W/2||k==W)
            {
                cout << "*";
            }
            else if (k==W-i || k==i)
            {
                cout << "*";
            }
            else
            {
                cout << " ";
            }
        }
        cout << endl;
    }
}
Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
JSIDHU
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 01 '23 at 21:37
  • The output of your program differs slightly from the desired output, when `DrawUKflag(19,19)` is called. – Andreas Wenzel Jun 01 '23 at 23:12
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 02 '23 at 00:45