CSharp 반복문의 활용(별짓기)

양승준·2025년 4월 2일

CSharp

목록 보기
12/20
post-thumbnail

시작하며

반복문의 활용이다. 띠용하면서, C#의 다른 기능들에 대해서 명시를 하려고 했지만 중간에 내가 정리해 놓은 반복문의 활용에 대해서 어떻게 이러한 생각을 가졌는지에 대해서 기록하고 미래에 내가 이 글을 다시 본다면 어떤 생각을 할지가 궁금해서 이렇게 글을 작성해야겠다 생각했다.


⭐ 별짓기

계단식 별짓기 부터 다이야몬드 별짓기, 다이야몬드 별짓기 경량하기 순서로 글을 작성하겠다.

📶 계단식 별짓기

계단식 별짓기 코드 1

namespace BuildingStar
{
    internal class Program
    {
        static char star = '*';
        static char blank = ' ';

        static void Main(string[] args)
        {
            int num = 5;

            BuildingStarPatten1(num);
            BuildingStarSimplePatten1(num);
        }
        
        static void BuildingStarPatten1(int num)
        {
            Console.WriteLine("==========1");
            for (int i = 0; i < num; i++)
            {
                for (int j = 0; j < i + 1; j++)
                    Console.Write(star);

                Console.WriteLine();
            }
        }

        static void BuildingStarSimplePatten1(int num)
        {
            Console.WriteLine("==========1");
            for (int i = 0; i < num; i++)
                Console.WriteLine(new string(star, i + 1));
        }
    }
}

==========1
*
**
***
****
*****
==========1
*
**
***
****
*****

이러한 식으로 별을 짓기를 한다.

  • 별은 해당 줄의 번호 만큼 별을 출력한다.

계단식 별짓기 코드 2

namespace BuildingStar
{
    internal class Program
    {
        static char star = '*';
        static char blank = ' ';

        static void Main(string[] args)
        {
            int num = 5;

            BuildingStarPatten2(num);
            BuildingStarSimplePatten2(num);
        }
        
        static void BuildingStarPatten2(int num) 
        {
            Console.WriteLine("==========2");
            for (int i = 0; i < num; i++)
            {
                for (int j = 0; j < num - (i + 1); j++)
                    Console.Write(blank);

                for (int j = 0; j < i + 1; j++)
                    Console.Write(star);

                Console.WriteLine();
            }
        }

        static void BuildingStarSimplePatten2(int num)
        {
            Console.WriteLine("==========2");
            for (int i = 1; i <= num; i++)
                Console.WriteLine(new string(blank, num - i) + new string(star, i));
        }
    }
}

==========2
    *
   **
  ***
 ****
*****
==========1
    *
   **
  ***
 ****
*****

이러한 식으로 별을 짓기를 한다.

  • 빈칸은 최대 줄 - 현재 줄의 번호 이다.
  • 별은 해당 줄의 번호 만큼 별을 출력한다.

계단식 별짓기 코드 3

namespace BuildingStar
{
    internal class Program
    {
        static char star = '*';
        static char blank = ' ';

        static void Main(string[] args)
        {
            int num = 5;

            BuildingStarPatten3(num);
            BuildingStarSimplePatten3(num);
        }
        
        static void BuildingStarPatten3(int num) 
        {
            Console.WriteLine("==========3");
            for (int i = 0; i < num; i++)
            {
                for (int j = 0; j < num - i; j++)
                    Console.Write(star);

                Console.WriteLine();
            }
        }

        static void BuildingStarSimplePatten3(int num)
        {
            Console.WriteLine("==========3");
            for (int i = 0; i < num; i++)
                Console.WriteLine(new string(star, num - i));
        }
    }
}

==========3
*****
****
***
**
*
==========3
*****
****
***
**
*

이러한 식으로 별을 짓기를 한다.

  • 별은 최대 줄 - 해당 줄의 번호 + 1 만큼 별을 출력한다.

계단식 별짓기 코드 4

namespace BuildingStar
{
    internal class Program
    {
        static char star = '*';
        static char blank = ' ';

        static void Main(string[] args)
        {
            int num = 5;

            BuildingStarPatten4(num);
            BuildingStarSimplePatten4(num);
        }
        
        static void BuildingStarPatten4(int num) 
        {
            Console.WriteLine("==========4");
            for (int i = 0; i < num; i++)
            {
                for (int j = 0; j < i + 1; j++)
                    Console.Write(blank);

                for (int j = 0; j < num - i; j++)
                    Console.Write(star);

                Console.WriteLine();
            }
        }

        static void BuildingStarSimplePatten4(int num)
        {
            Console.WriteLine("==========4");
            for (int i = 0; i < num; i++)
                Console.WriteLine(new string(blank, i) + new string(star, num - i));
        }
    }
}

==========4
*****
 ****
  ***
   **
    *
==========4
*****
 ****
  ***
   **
    *

이러한 식으로 별을 짓기를 한다.

  • 빈칸은 현재 줄의 번호 - 1 이다.
  • 별은 최대 줄 - 해당 줄의 번호 + 1 만큼 별을 출력한다.


💎 다이아몬드 별짓기

위의 계단 식 별짓기는 문제 없이 넘어 왔다. 그런데 다이야몬드라니??? 다이아~몬~드~...? (선넘네)
뭐 접근 방법 같은 경우는 위 아래를 따로 출력하자는 생각이여서 별짓기 기본이라고 하고 아래에 적었다.

다이야몬드 별짓기 기본

namespace BuildingStar
{
    internal class Program
    {
        static char star = '*';
        static char blank = ' ';

        static void Main(string[] args)
        {
            int num = 7;
            Console.WriteLine("\nBuilding Star Diamond Patten Func");
            BuildingStarDiamondPatten1(num);
        }
        
        static void BuildingStarDiamondPatten1(int num)
        {
            if (num <= 1 || num % 2 == 0) return;

            int i = 0;
            int topRow = (num / 2) + 1;
            int botRow = (num / 2);

            Console.WriteLine("for문 6개");
            // 위쪽
            for (i = 0; i < topRow; i++)
            {
                for (int j = 0; j < topRow - (i + 1); j++)
                    Console.Write(blank);

                for (int j = 0; j < (i * 2) + 1; j++)
                    Console.Write(star);

                Console.WriteLine();
            }

            // 아래쪽
            for (i = 0; i < botRow; i++)
            {
                for (int j = 0; j < i + 1; j++)
                {
                    Console.Write(blank);
                }

                for (int j = 0; j < (botRow - i) * 2 - 1; j++)
                {
                    Console.Write(star);
                }
                Console.WriteLine();
            }
        }
    }
}

Building Star Diamond Patten Func
for문 6개
   *
  ***
 *****
*******
 *****
  ***
   *

일단 다이아몬드 별짓기 같은 경우는 조건은 1과 짝수를 제외하고 입력을 받는것이다.
그렇다면 이제 생각해볼 것은? "다이아몬드면 별이 늘어나다가 줄어드는 시점의 분기를 어떻게 처리하는가" 가 이 다이아몬드의 핵심이라고 생각한다.

그래서 위쪽과 아래쪽을 나누어 생각하기로 하였다. 위에서 늘어나는 위쪽 홀수 처리, 아래는 줄어들기 시작하는 짝수 처리를 맡겨야하고 처리를 한다면 아래의 코드와 같이 쉽게 구상이 된다.


다이야몬드 별짓기 경량 1

namespace BuildingStar
{
    internal class Program
    {
        static char star = '*';
        static char blank = ' ';

        static void Main(string[] args)
        {
            int num = 7;
            Console.WriteLine("\nBuilding Star Diamond Patten Func");
            BuildingStarDiamondPatten2(num);
        }
        
        static void BuildingStarDiamondPatten2(int num)
        {
            if (num <= 1 || num % 2 == 0) return;

            int bCount = 0;
            int sCount = 0;

            int half = num / 2 + 1;

            Console.WriteLine("for문 3개");
            for (int i = 0; i < num; i++)
            {
                if (half <= i)
                {
                    bCount = i - num / 2; // -2 -1 0 1 2
                    sCount = (num - i) * 2 - 1; // 9 7 5 2 1
                }
                else
                {
                    bCount = num / 2 - i; // 2 1 0 -1 2
                    sCount = i * 2 + 1; // 1 3 5 7 9
                }

                for (int j = 0; j < bCount; j++)
                    Console.Write(blank);

                for (int j = 0; j < sCount; j++)
                    Console.Write(star);

                Console.WriteLine();
            }
        }
    }
}

Building Star Diamond Patten Func
for문 3개
   *
  ***
 *****
*******
 *****
  ***
   *

이렇게 해서 분기를 나누고 위와 아래의 출력 처리를 한곳에서 하게 되면서, for 문의 3개만 사용할 수 있게 되었다.

문제는 이제 이 코드를 줄여보는 것이다. 그럼 전환되는 분기말고도 규칙성을 찾아야된다.
찾은 규칙은 빈칸위와 아래가 같다이다. 그럼 이렇게 찾은 규칙을 코드로 작성한것이 아래의 코드이다.


다이야몬드 별짓기 경량 2

namespace BuildingStar
{
    internal class Program
    {
        static char star = '*';
        static char blank = ' ';

        static void Main(string[] args)
        {
            int num = 7;
            Console.WriteLine("\nBuilding Star Diamond Patten Func");
            BuildingStarDiamondPatten3(num);
        }
        
        static void BuildingStarDiamondPatten3(int num)
        {
            if (num <= 1 || num % 2 == 0) return;

            Console.WriteLine("for문 1개");
            int half = num / 2;

            for (int i = 0; i < num; i++)
            {
                // 중간을 기준으로 대칭적인 빈칸 개수
                int bCount = Math.Abs(half - i); // 3, 2, 1, 0, 1, 2, 3  
                // 전체 개수에서 빈칸을 제외한 별 개수
                int sCount = num - 2 * bCount; // 1, 3, 5, 7, 5, 3, 1

                Console.WriteLine(new string(blank, bCount) + new string(star, sCount));
            }
        }
    }
}

Building Star Diamond Patten Func
for문 1개
   *
  ***
 *****
*******
 *****
  ***
   *


이렇게 분기를 찾고, 해당 분기가 되어가면서 전환되는 규칙을 찾아서 활용하였다. 이번 코드의 핵신은 빈칸이다. 왜 위 코드의 빈칸이 핵심일까? 빈칸은 분명 줄어들다가 마이너스로 줄어든다. 그래도 부호를 제거 시 숫자는 대칭을 이룬다는 점이 주목할 점이다.

그런데 이 곳에서 봐야될 것은 그 빈칸의 숫자다.

이 빈칸의 수가 전체 줄수 - 2 * 빈칸의 수 를 한다면 해당 줄에 그려야될 별의 수가 나온다.
당연한 결과라고 할수 있다. 에초에 위에서 절반을 구하는 코드에서의 3과 절반 값에서 감소, 증가를 하는 빈칸의 수는 전체 줄수를 2로 나누었들 때 결정이 났다고 볼수 있다. 2와 절대값이 해당 코드의 핵심이라고 생각한다. (에초에 정수로 값을 받아서 기존의 값보다 작은 짝수로 나누는 상황이 연출되서 곱하기 3를 해도 최대 줄수를 넘길 수 없다. 넘어가게 설정을 해도 star 찍는 수는 음수로 넘어가게 된다.)


마치며

같은 기능이여도 더욱 간단하게 코드를 작성할 수 있다. 그러한 이유는 내가 하고자하는 것의 규칙성이 존재하는지변화가 일어나는 시점 을 관찰하는 관점과 시야가 중요하다는 것을 알게 되었다. 이 뒤에는 열거형과 구조체 등을 포스팅을 하겠다. 언능 포스팅하고 이렇게 생각을 할만한 거를 다시 포스팅하겠다.

핵심

규칙성이 존재하는지
변화가 일어나는 시점

profile
지모창말, 미모창.

0개의 댓글