N Log

별 찍기 역피라미드

문제

   0 1 2 3 4 5 6 7 8
0  * * * * * * * * *
1    * * * * * * *
2      * * * * *
3        * * *
4          *

해답

모양만 거꾸로일 뿐, 별 찍기 피라미드와 접근 방법은 동일하다.

공백과 별 개수를 계산해서 출력

#include <stdio.h>

int main()
{
    const int height = 5;

    for (int row = 0; row < height; row++)
    {
        int space_count = row;
        int star_count = 2 * (height - row) - 1;

        for (int col = 0; col < space_count; col++)
        {
            printf(" ");
        }

        for (int col = 0; col < star_count; col++)
        {
            printf("*");
        }

        printf("\n");
    }
}

역피라미드는 가운데 열인 4번 열을 기준으로 좌우 대칭이다.
전체 모양으로 보면 좌우 공백은 하나씩 늘어나지만, 실제 출력에서는 별 뒤의 공백을 출력하지 않아도 같은 모양이 된다.

  • 0행: 공백 0개, 별 9개
  • 1행: 공백 1개, 별 7개
  • 2행: 공백 2개, 별 5개
  • 3행: 공백 3개, 별 3개
  • 4행: 공백 4개, 별 1개

공백은 0행에서 0개이고, 행 번호가 1씩 증가할수록 공백 수도 1씩 늘어난다.
그래서 space_count를 현재 행 번호 row로 둔다.

별의 개수는 9, 7, 5, 3, 1 순서의 홀수로 줄어든다.
0행의 별 개수는 2 * height - 1로 구할 수 있고, 행이 1씩 증가할 때마다 2개씩 줄어든다.
이를 2 * (height - row) - 1로 표현하거나, 최대 별 개수 2 * height - 1을 미리 구해 두고 행마다 2씩 줄이는 방식으로 생각할 수도 있다.

출력 범위를 넓혀 피라미드 출력

#include <stdio.h>

int main()
{
    const int height = 5;

    for (int row = 0; row < height; row++)
    {
        for (int col = 0; col < height + (height - 1 - row); col++)
        {
            if (col >= row)
            {
                printf("*");
            }
            else
            {
                printf(" ");
            }
        }
        printf("\n");
    }
}

역피라미드는 아래처럼 왼쪽 모양과 오른쪽 모양으로 나누어 생각할 수 있다.

   0 1 2 3 4 | 5 6 7 8
0  * * * * * | * * * *
1    * * * * | * * *
2      * * * | * *
3        * * | *
4          * |

왼쪽 모양은 별 찍기 직각삼각형 4에서 다룬 형태와 같다.
각 칸의 좌표를 (row, col)로 나타냈을 때, col >= row인 칸에 별을 출력하고 나머지 칸에 공백을 출력하면 왼쪽 모양을 완성할 수 있다.

전체 그림을 완성하려고 왼쪽과 오른쪽을 따로 구현할 필요는 없다.
왼쪽을 출력하는 과정에서 출력 범위를 넓혀 오른쪽까지 출력되게 만들면 된다.
오른쪽에 추가로 출력하는 별의 개수는 처음에 height - 1개이다.
행이 증가할수록 별이 하나씩 줄어드므로, 여기에서 row를 빼 안쪽 반복문의 횟수를 height + (height - 1 - row)로 설정하면 된다.