많은 사람들이 C프로그래밍이나, 파이썬을 공부하면서, 콘솔창에서 *과 공백의 출력 조건식을 다루어 다양한 형태를 만들어내는 것으로 알고리즘 공부를 합니다.

 이에, 저도 부족한 알고리즘 공부를 위해 여러 *형태를 정해두고, 이를 조건식을 통해 구현해보는 연습을 해보았습니다.

(별 찍기는 시리즈로 진행하려 하기에, 2가지 만 진행해보겠습니다.)

ngc869, ngc884 : 페르세우스 2중성단

 

//--------------------------------------------------------------------------------

 

문제 1 : 다음 형태의 프로그램을 구현하시오.

문제 2 : 문제 1의 소스를 바탕으로 다음 형태의 프로그램을 구현하시오.

 

 

//--------------------------------------------------------------------------------

 우선 완성되어, 동작하는 소스코드를 보며 정리해보도록 하겠습니다.

 

제가 하나하나 작성한, 문제 1번을 위한 소스코드 입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void) {
    int scale = 0;
 
    printf("크기 : ");
    scanf("%d"&scale);
 
    //scale의 크기만큼 세로로 반복합니다.
    for (int col = 0; col < scale; col++) {
        //scale의 크기만큼 가로로 반복합니다.
        for (int row = 0; row < scale; row++) {
            //y = -x 그래프의 4사분면 반직선과 같이, *을 출력합니다.
            if (col == row) {
                printf("*");
            }
 
            //y = (scale) - x 그래프의 1사분면과 같이, *을 출력합니다.
            else if (scale - 1 - col == row) {
                printf("*");
            }
 
            //*이 x의 형태로 그려지는 구역 함수 이외의 지점은 공백을 출력합니다.
            else {
                printf(" ");
            }
        }
        printf("\n");
    }
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

 별 찍기 시리즈의 거의 제일 기초적인 형식입니다. 때문에 조건문 흐름, 그리고 머릿속에서 가볍게 인덱싱해볼 수 있는 능력만 있다면 충분회 디버깅 없이 한번에 마무리할 수 있는 난이도 입니다.

 

여기서 주목할 만한 점은,

- if, else if, else 조건문의 흐름

- 조건문에 넣어주는 조건식의 간결함

정도 인 것 같습니다.

 

 if, else if, else로 세그먼트를 잘 나누어 프로그래밍 하는 것과, if문 만을 사용하고, 추가적인 조건문을 더 넣어 프로그래밍하는 것에는 천지차이가 있습니다.

 개발의 간결함을 제외하고도, 프로그램이 진행되면서 지나는 조건식의 횟수 또한 현저히 달라지기 때문에, 적절히 묶을 수 있는 조건문끼리는 같은 세그먼트로 분류하여 조금 더 효율적으로 프로그래밍 할 수 있어야 합니다.

 

 

 그리고 인덱싱을 머리속으로 몇 번 해보다보면 이게 또 적응이 되어 꽤 할만해집니다. 조건식의 인덱싱을 어떻게 달지 조금 헷갈려서 이것저것으로 바꿔보면서 프로그래밍 하는 것과, 머릿 속으로 계산한 인덱싱 조건을 대입하는 것은 차원이 다릅니다. (이게 또 가끔 주솟값을 읽어드려서 연산해버리는데, 필요로 하는 값과 비슷한 크기면 찾기도 어려우니,,,, 몹시 조심해야합니다..!)

 

 

 

 

//--------------------------------------------------------------------------------

제가 작성한, 문제 2번을 위한 소스코드 입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void) {
    int scale = 0;
 
    printf("크기 : ");
    scanf("%d"&scale);
 
    //scale의 크기만큼 세로로 반복합니다.
    for (int col = 0; col < scale; col++) {
        //scale의 크기만큼 세로로 반복합니다.
        for (int row = 0; row < scale; row++) {
            //y = -x 그래프의 4사분면 반직선과 같이, *을 출력합니다.
            if (col == row) {
                printf("*");
            }
 
            //y = (scale) - x 그래프의 1사분면과 같이, *을 출력합니다.
            else if (scale - 1 - col == row) {
                printf("*");
            }
 
            //칠해지는 구역에서 윗부분의 *을 출력하는 논리식 입니다.
            else if ((col < scale / 2 && col>row) || (col < scale / 2 && scale - 1 - col < row)) {
                printf("*");
            }
 
 
            //칠해지는 구역의 중앙 줄에 *을 출력하는 논리식 입니다.
            else if (col == scale / 2) {
                printf("*");
            }
 
            //칠해지는 구역에서 아랫부분의 *을 출력하는 논리식 입니다.
            else if ((col > scale / 2 && col < row) || (col > scale / 2 && scale - 1 - col > row)) {
                printf("*");
            }
 
            //*이 x의 형태로 그려지는 구역 함수 이외의 지점은 공백을 출력합니다.
            else {
                printf(" ");
            }
        }
        printf("\n");
    }
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

 기본적인 알고리즘은 문제 1번과 같습니다.

 하지만, 문제에서는 원점을 중심으로 나눠진 X 형태의 구역에서 왼쪽, 오른쪽 영역을 *들로 꽉 채워 출력하고 싶어합니다.

 제가 한번에 처리할 수 있는 조건식을 구상해낼 수있는 사람이었다면 아마 어디선과 과제 대행 알바를 하고있었을 겁니다ㅎㅎ; 하지만 저는 그런 사람이 아니니, 영역을 나누어서 조건식을 세웠습니다.

 

 //칠해지는 구역에서 윗부분의 *을 출력하는 논리식 입니다.

            else if ((col < scale / 2 && col>row) || (col < scale / 2 && scale - 1 - col < row)) {

                printf("*");

            }

위 코드를 살펴봅시다.

 

 y = -x 형태의 그래프 보다는 작으면서, x축 위로의 좌표들, 그리고 y = x 형태의 그래프보다는 작으면서 x축 위로의 좌표들을 우선 나누었습니다.

 이 점들의 공통점을 보다보니, column이 전체 스케일의 절반보다 작다는 것이 있었습니다.

 이를 통해, 논리연산자로 그렇게 복잡하지 않게 구현할 수 있었습니다.

 

 

 

 

 //칠해지는 구역에서 아랫부분의 *을 출력하는 논리식 입니다.

            else if ((col > scale / 2 && col < row) || (col > scale / 2 && scale - 1 - col > row)) {

                printf("*");

            }

x축 아래로의 구역도 위와 같은 원리로, column이 전체 스케일의 절반보다는 크다는 것을 조건식으로 묶어 구현해낼 수 있었습니다.

 

 

 

//칠해지는 구역의 중앙 줄에 *을 출력하는 논리식 입니다.

            else if (col == scale / 2) {

                printf("*");

            }

오히려 중앙의 x축 근처의 좌표들을 처리하는데에 시간을 많이 소모하게 됩니다.

홀수일 때는 x축이 하나, 그리고 scale이 짝수일 때는 x축이 두 줄이기 때문입니다.

 

 저는 알고리즘 공부를 정식으로 해본적이 없기에, 중복으로 겹치기는 하지만 어쨌든 위처럼 column 이 scale의 절반과 같을 때는 모두 출력한다는 식을 세웠습니다.

 

중복된다는 점에서, 누구든지 저보다 훌륭한 소스코드를 다시 생산해낼 수 있을 것이라고 생각합니다.

'C프로그래밍' 카테고리의 다른 글

[C언어] 하노이탑  (1) 2020.04.16
[C언어] 행렬의 연산 - 1  (0) 2020.03.30

+ Recent posts