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 = height - 1 - row;
        int star_count = 2 * row + 1;

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

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

        printf("\n");
    }
}

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

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

공백이 최대로 출력되는 개수는 0행에서 4개이므로 height에서 1을 빼 space_count의 최댓값을 4로 맞춘다.
그다음 행 번호 row만큼 빼면 행 번호가 1씩 증가할수록 공백 수도 1씩 줄어든다.

별의 개수는 1, 3, 5, 7, 9 순서의 홀수로 늘어난다.
홀수는 2 * k + 1 형태로 표현할 수 있으므로, 현재 행 번호 row를 사용해 star_count2 * row + 1로 계산한다.

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

#include <stdio.h>

int main()
{
    const int height = 5;

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

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

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

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

전체 그림을 완성하려고 왼쪽과 오른쪽을 따로 구현할 필요는 없다.
왼쪽을 출력하는 과정에서 출력 범위를 넓혀 오른쪽까지 출력되게 만들면 된다.
오른쪽 모양은 행이 증가할수록 별이 하나씩 늘어나므로, 안쪽 반복문의 횟수를 height + row로 설정하면 된다.