N Log

별 찍기 공백 역피라미드

문제

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

해답

앞의 별 찍기 역피라미드 문제는 별이 빈틈없이 붙어 있고, 별 개수가 9, 7, 5, 3, 1처럼 홀수로 줄어드는 형태였다.
이번 공백 역피라미드는 별 개수가 행마다 1개씩 감소하고, 별과 별 사이에 공백이 들어간다.

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

#include <stdio.h>

int main()
{
    const int height = 5;

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

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

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

            if (col < star_count - 1)
            {
                printf(" ");
            }
        }

        printf("\n");
    }
}
  • 0행: 앞 공백 0개, 별 5개, 별 사이 공백 4개
  • 1행: 앞 공백 1개, 별 4개, 별 사이 공백 3개
  • 2행: 앞 공백 2개, 별 3개, 별 사이 공백 2개
  • 3행: 앞 공백 3개, 별 2개, 별 사이 공백 1개
  • 4행: 앞 공백 4개, 별 1개, 별 사이 공백 0개

앞 공백 수는 0부터 시작해서 행이 1씩 증가할 때마다 1씩 증가한다.
따라서 현재 행 번호인 row로 앞 공백 수를 구할 수 있다.

각 행마다 필요한 별의 수는 height에서 행 번호만큼 줄어든다.
따라서 height - row로 별의 수를 구할 수 있다.

별과 별 사이의 공백은 별을 출력한 뒤 공백을 바로 출력하는 방식으로 처리할 수 있다.
printf("* ")처럼 별과 공백을 한 번에 출력할 수도 있지만, 이 방식은 마지막 별 뒤에도 공백이 하나 더 붙는다.
따라서 정확한 출력을 위해 마지막 별이 아닐 때만 공백을 출력한다.

칸마다 조건 판단해 출력

#include <stdio.h>

int main()
{
    const int height = 5;
    const int width = 2 * height - 1; // 9

    for (int row = 0; row < height; row++)
    {
        int first_star_col = row;
        int last_star_col = width - 1 - row;

        for (int col = 0; col < width; col++)
        {
            if (first_star_col <= col && col <= last_star_col && (col - first_star_col) % 2 == 0)
            {
                printf("*");
            }
            else
            {
                printf(" ");
            }
        }

        printf("\n");
    }
}

이 방법은 행 5줄, 열 9칸, 총 45칸을 순회하면서 각 칸에서 조건을 판단해 별이나 공백을 출력한다.

width는 별과 공백을 포함해 한 줄에 필요한 전체 열의 개수다.
가장 윗줄에는 별 5개와 별 사이 공백 4개가 필요하므로 전체 9칸이 필요하다.

별이 찍히는 위치를 (row, col) 좌표로 바라보면 다음과 같다.

  • 0행: (0,0) (0,2) (0,4) (0,6) (0,8)
  • 1행: (1,1) (1,3) (1,5) (1,7)
  • 2행: (2,2) (2,4) (2,6)
  • 3행: (3,3) (3,5)
  • 4행: (4,4)

현재 행 번호를 row라고 하면 첫 번째 별이 찍히는 좌표는 (row, row), 마지막 별이 찍히는 좌표는 (row, width - 1 - row)로 볼 수 있다.
그래서 first_star_collast_star_col은 현재 행에서 첫 번째 별과 마지막 별이 찍히는 열 번호다.
colfirst_star_collast_star_col 사이에 있다면 별을 찍을 수 있는 범위 안에 있는 것이다.
하지만 이 범위 안의 모든 칸에 별을 찍으면 출력 결과가 일반 역피라미드와 같아진다.

규칙을 다시 살펴보면 각 행의 별은 첫 번째 별부터 열 번호가 2씩 증가하는 위치에 찍힌다.
col - first_star_col은 그 행의 첫 번째 별 위치에서 현재 칸까지 떨어진 열 수를 의미한다.
따라서 col - first_star_col이 0, 2, 4처럼 짝수인 칸에만 별을 찍어야 한다.