C# - 콘솔로 별 찍기 (다이아몬드 편)
지난 글에서는 콘솔로 삼각형을 찍어봤다.
이번에는 그것 보다 조금 더 심화 버전인 다이아몬드를 찍어볼 것이다.

바로 이게 이번에 해볼 내용이다.
주어진 조건은 다음과 같다.
- 출력할 다이아몬드 형태를 사용자로부터 입력 받은 후, 만약 짝수일 경우 홀수를 다시 입력하라고 유저에게 무한 반복으로 요구한다.
- 홀수가 입력되었을 경우, 다이아몬드 중간 부분이 유저의 입력과 같은 다이아몬드를 출력하는 프로그램 제작.
그럼 바로 시작해보자.
우선 while문과 if문, TryParse와 Console.ReadLine을 이용해 입력 받는 부분을 정의한다.
문제 푸는 것만이 목적이라 이렇게까지 예외처리를 할 필요는 없다고 생각할 수 있지만 그래도 일단 해보자.
using System;
namespace CsharpStudy
{
internal class Program
{
static void Main()
{
// 입력 받은 숫자 넣을 변수
int total;
// 정상 입력시까지 무한 반복
while (true)
{
// 정상 입력했는지 여부 판단
if (int.TryParse(Console.ReadLine(), out total))
{
// 1 입력 금지 (다이아몬드가 성립이 안됨)
if (total == 1)
{
Console.WriteLine("1이 아닌 값을 입력하세요");
}
// 짝수 입력 금지. (조건에 홀수만 입력이라 돼있음)
else if (total % 2 == 0)
{
Console.WriteLine("홀수를 입력하세요");
}
else
{
// 문제 없으면 무한루프 끝냄
break;
}
}
else
{
Console.WriteLine("1이 아닌 홀수 값을 입력하세요");
}
}
}
}
}
왜 티스토리 코드블럭 들여쓰기가 이상하게 틀어지는지 모르겠다... 무슨 버그인가...
이렇게 홀수를 제대로 입력할 때까지 무한 반복하는 루프를 만들어서 total에 입력값을 넣어주자.
이제 이 total 수만큼 반복문을 돌릴 수 있도록 반복문 부분을 작성해보자.
우선 다이아몬드를 만들려면 중간점까지 *의 수가 증가하다가, 중간점 이후로는 *의 수가 감소해야한다.
그래서 일단 중간점을 정의해준 뒤에, 2중 for문을 통해 위쪽과 아래쪽을 각각 그려줄 것이다.
using System;
namespace CsharpStudy
{
internal class Program
{
static void Main()
{
// 입력 받기
int total;
while (true)
{
if (int.TryParse(Console.ReadLine(), out total))
{
if (total == 1)
{
Console.WriteLine("1이 아닌 값을 입력하세요");
}
else if (total % 2 == 0)
{
Console.WriteLine("홀수를 입력하세요");
}
else
{
break;
}
}
else
{
Console.WriteLine("1이 아닌 홀수 값을 입력하세요");
}
}
// 중간점 정의
int mid = total / 2;
// 방법 1: 2중 for문
Console.WriteLine("2중 for문을 이용한 방법");
Console.WriteLine();
for (int i = 1; i <= total; i++)
{
// 위쪽
if (i <= mid)
{
for (int j = i; j <= mid; j++)
{
Console.Write(" ");
}
for (int k = 0; k < i * 2 - 1; k++)
{
Console.Write("*");
}
Console.WriteLine();
}
// 아래쪽
if (i > mid)
{
for (int j = 1; j < i - mid; j++)
{
Console.Write(" ");
}
for (int k = 0; k < 2 * (total - i) + 1; k++)
{
Console.Write("*");
}
Console.WriteLine();
}
}
}
}
}

짝수도 잘 걸러주고 제대로 다이아몬드가 출력된다.
삼각형을 한번 그리고 와서 그런지 생각보다 굉장히 간단하게 구현할 수 있었다.
그래서 삼각형때처럼 다른 방식으로도 구현해볼 것이다.
입력 받는 곳까지는 동일하게 구성하고, 출력 부분을 new string을 이용해 간결하게 출력할 것이다
삼각형 구현에서 입력값이 500 정도 쯤 되면 성능 차이가 100배 이상 나는 걸 확인했으니 이걸 사용하는 게 가독성 면에서나 성능 면에서나 편의성 면에서나 좋다고 볼 수 있다.
using System;
namespace CsharpStudy
{
internal class Program
{
static void Main()
{
// 입력 받기
int total;
while (true)
{
if (int.TryParse(Console.ReadLine(), out total))
{
if (total == 1)
{
Console.WriteLine("1이 아닌 값을 입력하세요");
}
else if (total % 2 == 0)
{
Console.WriteLine("홀수를 입력하세요");
}
else
{
break;
}
}
else
{
Console.WriteLine("1이 아닌 홀수 값을 입력하세요");
}
}
// 중간점 정의
int mid = total / 2;
// 방법 2: new string
for (int i = 0; i < total; i++)
{
if (i <= mid)
{
Console.Write(new string(' ', mid - i));
Console.WriteLine(new string('*', i * 2 + 1));
}
else if (i > mid)
{
Console.Write(new string(' ', i - mid));
Console.WriteLine(new string('*', 2 * (total - i) - 1));
}
}
}
}
}
2중 for문이 사라진 것만으로도 이렇게나 보기 좋다.
아래는 두 코드의 성능 비교 표다
| 입력값 | 2중 for문 | new string |
| 7 | 0.82ms | 0.17ms |
| 77 | 64.67ms | 2.06ms |
| 777 | 5323.39ms | 32.50ms |
그리고 여기서 조금 더 코드를 최적화할 수 있다
using System;
namespace CsharpStudy
{
internal class Program
{
static void Main()
{
// 입력 받기
int total;
while (true)
{
if (int.TryParse(Console.ReadLine(), out total))
{
if (total == 1)
{
Console.WriteLine("1이 아닌 값을 입력하세요");
}
else if (total % 2 == 0)
{
Console.WriteLine("홀수를 입력하세요");
}
else
{
break;
}
}
else
{
Console.WriteLine("1이 아닌 홀수 값을 입력하세요");
}
}
// 중간점 정의
int mid = total / 2;
for (int i = 0; i < total; i++)
{
int spaces = Math.Abs(mid - i);
int chars = total - 2 * spaces;
Console.Write(new string(' ', spaces));
Console.WriteLine(new string('*', chars));
}
}
}
}
중간점 mid를 정의했으니, Math.Abs를 이용해 절대값을 구하는 것으로 라인별로 출력해야할 공백과 *의 수를 구할 수 있다.
성능 차이는 아주 미세해서 굳이 비교는 하지 않았다.
어느 코드가 더 보기 좋고 좋은 코드일지는 사람마다 다르지 않을까 싶다.
이렇게 앞에서 배운 내용들과 조금의 +@를 통해서 콘솔로 삼각형과 다이아몬드를 그려보았다.
혹시 더 좋은 방법이 있으면 절대 기분나빠하지 않고 오히려 감사히 배울테니 얼마든지 지적 및 훈수해주셨으면 한다.
'C#' 카테고리의 다른 글
| C# - 값 타입 (Value Type), 참조 타입 (Reference Type) (0) | 2025.09.10 |
|---|---|
| C# - 배열 ( Array ) (0) | 2025.09.08 |
| C# - 콘솔로 별 찍기 (삼각형 편) (0) | 2025.09.04 |
| C# - 반복문 ( Loop Statements ) (0) | 2025.09.04 |
| C# - 조건문 ( Conditional Statements ) (0) | 2025.09.04 |