Minwoo Dev.

<윤성우의 열혈 C프로그래밍> :: 20. 도전! 프로그래밍 3 문제풀이 본문

C++

<윤성우의 열혈 C프로그래밍> :: 20. 도전! 프로그래밍 3 문제풀이

itisminu 2023. 9. 8. 11:25
728x90
반응형
SMALL

도전 1

길이가 4 x 4인 int형 2차원 배열을 선언하고, 모든 요소를 아래 그림의 왼쪽에 있는 형태와 동일하게 초기화하자. 그리고 배열의 요소들을 오른쪽 방향으로 90도씩 이동시켜서 그 결과를 출력하는 프로그램을 작성해보자. 참고로 배열이 변경되는 형태는 다음과 같다.

 

정답

#include<stdio.h>

void Turn90do(int (*arr)[4])
{
    int arr2[4][4];
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            arr2[j][3-i] = arr[i][j];
        }
    }
    
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            arr[i][j] = arr2[i][j];
        }
    }
}

void ShowArray(int (*arr)[4])
{
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            printf("%d\t",arr[i][j]);
        }
        printf("\n");
    }
    printf("\n\n");
}


int main(void)
{
    int arr[4][4] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
    int arr2[4][4];

    printf("Before Turn\n");
    ShowArray(arr);

    Turn90do(arr);
    printf("First Turn\n");
    ShowArray(arr);

    Turn90do(arr);
    printf("Second Turn\n");
    ShowArray(arr);

    Turn90do(arr);
    printf("Third Turn\n");
    ShowArray(arr);

    Turn90do(arr);
    printf("Fourth Turn(Again Before Turn)\n");
    ShowArray(arr);

    return 0;
}

 

 

도전 2    *** 다시 복습하기

달팽기 배열을 만들어서 이를 출력하는 프로그램을 작성하고자 한다. 여기서 말하는 달팽이 배열은 다음과 같다.

 

정답

#include<stdio.h>

int arr[100][100];
int count = 1;

void Left_to_Right(int row, int min, int max)
{
    for(int i=min;i<max;i++){
        arr[row][i] = count;
        count++;
    }
}

void Right_to_Left(int row, int max, int min)
{
    for(int i=max-2;i>=min;i--){
        arr[row][i] = count;
        count++;
    }
}

void Top_to_Bottom(int col, int min, int max)
{
    for(int i=min+1;i<max;i++){
        arr[i][col] = count;
        count++;
    }
}

void Bottom_to_Top(int col,int max, int min)
{
    for(int i=max-2;i>=min+1;i--){
        arr[i][col] = count;
        count++;
    }
}

void Snail(int n)
{
    int min = 0;
    int max = n;

    for(int i=0;i<n/2;i++){
        Left_to_Right(i,min,max);
        Top_to_Bottom(n-1-i,min,max);
        Right_to_Left(n-1-i,max,min);
        Bottom_to_Top(i,max,min);
        min++;
        max--;
    }

    if(n%2==1){
        arr[n/2][n/2] = count;
    }
}


int main(void)
{
    int n;
    
    printf("숫자를 입력하세요 : ");
    scanf("%d",&n);

    Snail(n);

    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            printf("%3d ",arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}

 

소스 코드 출처 - [윤성우의 열혈 C프로그래밍] 도전 프로그래밍3 풀이 (velog.io)

 

[윤성우의 열혈 C프로그래밍] 도전 프로그래밍3 풀이

분명 C언어 공부 1번 2번 풀다가 때려쳤던 기억이 있는데 스무스하게 잘 풀려서 코테 짬이 쌓였구나 싶었다. 1 2 3 4 5 6

velog.io

 

도전 3

프로그램을 구현하다 보면 난수(Random Number)를 발생시켜야 하는 경우가 종종 있다. 여기서 말하는 난수란 임의의, 정해지지 않은, 무엇이 될지 모르는 수를 의미한다. 그런데 다행인 것은 ANSI  표준에서 난수를 생성할 때 호출할 수 있는 다음 함수를 제공하고 있다는 것이다.

#include<stdlib.h>

int rand(void); // 의사 난수(pseudo-random number) 반환

 

ASNI 표준에서는 이렇게 난수를 생성할 때 사용할 수 있는 함수 rand를 제공하고 있다. 이 함수의 사용방법은 다음과 같다.

 

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
    int i;
    printf("난수의 범위 : 0부터 %d까지\n",RAND_MAX);
    for(i=0;i<5;i++)
        printf("난수 출력 : %d\n",rand());
    return 0;
}

 

 

그럼 이어서 문제를 제시하겠다. 위의 예제에서는 0이상 RAND_MAX 이하의 난수를 총 5개 생성하고 있다. 이 예제를 적절히 변경해서 0이상 99 이하의 난수를 총 5개 생성하는 프로그램을 작성해보자. (힌트 : % 연산자를 적절히 활용하면 된다.)

 

정답

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
    int i;
    printf("난수의 범위 : 0부터 100까지\n");
    for(i=0;i<5;i++)
        printf("난수 출력 : %d\n",rand()%100);
    return 0;
}

 

 

 

 

도전 4

도전 3에서 제시한 예제를 여러 번 실행해보면 한가지 특징을 발견할 수 있다. 그것은 출력되는 난수가 규칙적이라는 것이다. 예를 들어서 처음 실행했을 때 생성된 난수가 21, 1, 43, 13, 2이라면 몇번을 실행해도 그 값이 그대로 출력된다. 그리고 이는 분명히 문제다 ! 왜냐하면 이렇게 되면 예측이 가능하기 때문에 진짜 난수라고 할 수 없기 때문이다. 그래서 rand 함수가 반환하는 난수를 가리켜 '의사 난수(pseudo-random number)' 라 하는 것이다. 의사 난수는 가짜 난수를 의미한다. 그래서 ANSI 표준에서는 이러한 문제를 어느정도 해결할 수 있도록 srand라는 함수를 정의하였다.

#include<stdlib.h>

void srand(unsigned int seed); // 발생할 난수의 씨드 값 지정

 

위의 함수는 하나의 값을 전달받는다. 그리고 그 전달된 값은 난수를 생성하는데 필요한 씨앗으로 사용된다. 그래서 이 값을 가리켜 씨드(seed) 값이라 한다. '콩 심은데 콩 나고, 팥 심은 데 팥 난다.' 라는 속담이 있듯이, 씨드 값이 무엇이냐에 따라서 rand 함수가 반환하는 난수의 형태가 달라진다. 그럼 다음 예제를 통해서 난수 생성에 필요한 씨앗을 심어보겠다.

#include<stdio.h>
#include<stdlib.h>

int main(void){
    int seed, i;
    printf("씨드 값 입력 : ");
    scanf("%d",&seed);
    srand(seed);

    for(i=0;i<5;i++){
        printf("정수 출력: %d\n",rand());
    }
    return 0;
}

위 예제 8행에서는 프로그램 사용자로부터 씨드 값을 입력 받아서 9행에서 srand의 인자로 전달하고 있다. 즉, 씨앗을 하나 심은 것이다. 씨앗을 심었으니 열매를 거둬야한다. 12행에서는 rand 함수를 이용하여 열매를 거둬들이고 있다.

 

srand 함수도 공부했으니 이제 제법 그럴듯한 난수를 발생시킬 수 있겠는가 ? 아니다! 여전히 문제는 남아있다. 위 예제처럼 프로그램을 실행할 때마다 씨드 값을 입력받을수는 없는 노릇 아닌가 ? 설사 입력받는다 해도 매번 다른 값을 입력받는다는 가정을 세우는 것은 무리가 있다. 그런데 이에 대한 해결책이 하나 있다. 시스템 시간을 이용하는 것이다. 현재 여러분 컴퓨터의 시간값을 얻어와서 srand 함수의 인자로 전달하는 것이다. 컴퓨터의 시간은 계속 변하기 때문에 매번 다른 씨앗을 얻는 도구로 활용이 가능하다. 그렇다면 컴퓨터의 현재시간을 어떻게 얻어와야 할까 ? 헤더파일 time.h에 선언되어 있는 time 이라는 이름의 함수를 사용하면 된다. 이 함수는 컴퓨터의 현재시간과 1970년 1월 1일 이후의 시간적 차를 초단위로 계산해서 반환해준다. 우리는 정확한 시간을 얻겠다는 것이 아니고 프로그램 실행 시마다 다른 정수 하나를 얻겠다는 것이므로 이 정도면 충분하다. 그럼 이를 적용한 예제를 제시하겠다. 실제로 매 실행 시마다 출력되는 난수가 다름을 확인할 수 있을 것이다.

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void){
    int i;
    srand((int)time(NULL));
    for(i=0;i<5;i++)
        printf("정수 출력 : %d\n",rand());

    return 0;
}

 

 

위 예제 8행에서는 time 함수를 호출하면서 인자로 NULL을 전달하고 있다. 이렇듯 단순히 시간정보를 반환받는 것이 목적이라면 NULL을 전달하면 된다. 자! 그럼 문제를 제시하겠다. 두 개의 주사위를 던졌을 때 결과를 출력하는 프로그램을 작성해보자. 물론 그 결과는 예측이 불가능해야 한다.

 

 

정답

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void){
    int i;
    srand((int)time(NULL));
    for(i=0;i<2;i++)
        printf("주사위 %d의 결과 : %d\n",i+1,rand()%5+1);

    return 0;
}

 

 

도전 5

가위 바위 보 게임을 만들어보자. 사용자로부터 가위 바위 보 중에서 하나를 입력받는다. 그리고 컴퓨터는 난수 생성을 통해서 가위 바위 보 중에서 하나를 선택하게 한다. 이 둘을 비교해서 승자와 패자를 가려주는 프로그램을 작성해 보자. 단 프로그램의 진행은 사용자가 질 때까지 계속되어야 하고, 마지막에 가서는 게임의 결과(예 : 4승3무)까지 출력해 주도록 하자.

 

정답

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void){
    int n;
    srand((int)time(NULL));
    int com = rand()%3+1;

    int win=0, tie = 0, lose = 0;


    while(lose==0){
        
    printf("가위는 1, 바위는 2, 보는 3 : ");
    scanf("%d",&n);
        if(n==1 && com==2){
            lose++;
        }
        else if(n==2 && com==1){
            win++;
        }
        else if (n==2 && com==3)
        {
            lose++;
            break;
        }
        else if (n==3 && com==2)
        {
            win++;
        }
        else if (n==1 && com==3)
        {
            win++;
        }
        else if (n==3 && com==1)
        {
            lose++;
            break;
        }
        else if (n==com)
        {
            tie++;
        } 
    }

    printf("결과 : %d승%d무\n",win,tie);
    return 0;
}

 

 

 

도전 6

친구와 둘이서 숫자 맞추기 게임을 해 본 적이 있을 것이다(보통의 야구 게임이라고 불린다.) 이것을 컴퓨터와 할 수 있도록 프로그램을 작성해보자. 게임의 방식은 다음과 같다. 

컴퓨터는 0에서 9 사이의 숫자 중에서 서로 다른 세 개의 숫자를 고르고, 사용자는 이것을 맞춰야 한다. 중요한 것은 숫자의 순서까지 정확히 맞춰야 한다는 것이다. 단 사용자가 예상한 숫자를 입력할 때마다 컴퓨터는 입력된 숫자와 컴퓨터 자신이 생각한 숫자가 얼마나 비슷한지를 알려줘야 한다.

예를 들어서 컴퓨터가 고른 숫자가 1 4 9 이고, 사용자가 입력한 숫자가 4 0 9이면, 두 개의 숫자는 4와 9가 일치한다. 9는 숫자와 위치까지 일치하지만(1 strike), 4는 숫자만 일치한다(1 ball), 이런 경우 컴퓨터는 다음과 같은 메세지를 출력해 준다.

1 strike, 1 ball

만약에 사용자가 1 4 9를 입력하였다면 "3 strike, 0 ball"이 되어서 프로그램은 종료가 된다. 이때 몇번만에 3 strike를 얻어냈는지에 대해서도 출력해 주기로 하자.(진행하면서 "몇 번째 도전입니다." 라는 메세지를 출력해줘도 좋다.)

 

 

정답

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void){
    int n[3];
    int c[3];
    int strike = 0, ball = 0;
    int count = 0;
    srand(time(NULL));

    for(int i=0;i<3;i++){
        c[i] = rand()%10;
    }

    printf("Start Game!\n");

    while(strike!=3){
        printf("3개의 숫자 선택: ");
        scanf("%d %d %d",&n[0],&n[1],&n[2]);
        count++;

        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                if(c[i]==n[j]){
                    if(i==j){
                        strike++;
                    }
                    else{
                        ball++;
                    }
                }
            }
        }

        if(strike==3){
            printf("%d번만에 성공!\n",count);
            break;
        }
        printf("%d번째 결과 : %d strike, %d ball\n",count,strike,ball);
        strike = 0;
        ball = 0;

    }
    
    return 0;
}

 

 

같은 수를 여러 개 입력했을 때 ball의 카운팅에도 입력되는 문제 발생.

 

 

728x90
반응형
LIST