질문 원본 : https://gall.dcinside.com/programming/2332356
지금 컴터에 있는 비주얼 스튜디오는 C99가 아니라 코드 존재 자체를 거부하길래 온라인 컴파일러로 테스트함
위 아래 코드가 같음
아래 있는 매개변수의 -를 + 로 바꿔줌
작동함
근데 숫자가 6 넘어가면 뻗음
배열 두 줄 채울 때마다 이 친구가 배열을 전부 곱해서 검사하는 게 문제인 거 같음.
배열에서 0을 발견했으면 그 즉시 빤스런 하라고 시킴
그리고 이 친구는 왜 무조건 처음 한번만 작동 시킬 거면서 반복문 안에 있음
반복문 밖으로 꺼내고 다른 거 만지기 귀찮아서 x를 2부터 시작하게 바꿈
잘됨
10 보다 큰 수도 테스트는 했는데 지저분 하게 보여서 안 가져옴
그 외에
자신의 포인터 다루는 솜씨를 뽐내는 건지 전역변수에 포인터 지정은 왜 한건지 모르겠지만 이건 당장 체감 성능이랑 관계도 없고,
이거 하나 바꾸려면 엮인 식이 너무 많아서 수정 안 함
전체 코드임
#include <stdio.h>
int void1 = 0;
int void2 = 0;
int *pn1 = &void1;
int *pn2 = &void2;
int checkarr(int length, int (*arr1)[length])
{
int num1 = 1;
for (int n1 = 0; n1 < length; n1++)
{
for (int n2 = 0; n2 < length; n2++)
{
if((arr1[n1][n2]) == 0)
{
num1 = 0;
n1 = length;
break;
}
}
}
return num1;
}
void voidarr(int length, int (*arr1)[length])
{
for (int n1 = 0; n1 < length; n1++)
{
for (int n2 = 0; n2 < length; n2++)
{
arr1[n1][n2] = 0;
}
}
}
void printfarr(int length, int (*arr1)[length])
{
for (int n1 = 0; n1 < length; n1++)
{
for (int n2 = 0; n2 < length; n2++)
{
printf("%3d", arr1[n1][n2]);
}
printf("\n");
}
}
void _arr(int length, int (*arr1)[length], int n1, int n2, int n3, int *pn3, int n4)
{
if (n4 == 0)
{
{
do
{
if (arr1[n1][n2] == 0)
{
arr1[n1][n2] = n3;
n3++;
n2++;
}
else
break;
} while (!((n2 == 0) || (n2 == length)));
}
*pn2 = n2 - 1;
}
else
{
do
{
if (arr1[n1][n2] == 0)
{
arr1[n1][n2] = n3;
n3++;
n2--;
}
else
{
break;
}
} while (!((n2 == -1) || (n2 == length)));
*pn2 = n2 + 1;
}
*pn1 = n1;
*pn3 = n3;
}
int larr(int length, int (*arr1)[length], int n1, int n2, int n3, int *pn3, int n4)
{
if (n4 == 0)
{
{
do
{
if (arr1[n1][n2] == 0)
{
arr1[n1][n2] = n3;
n3++;
n1++;
}
else
{
break;
}
} while (!((n1 == 0) || (n1 == length)));
*pn1 = n1 - 1;
}
}
else
{
do
{
if (arr1[n1][n2] == 0)
{
arr1[n1][n2] = n3;
n3++;
n1--;
}
else
{
break;
}
} while (!((n1 == -1) || (n1 == length)));
*pn1 = n1 + 1;
}
*pn2 = n2;
*pn3 = n3;
}
int main(int argc, char *argv[])
{
int x = 2;
int a;
int b = 1;
int *pb = &b;
scanf("%d", &a);
int arr1[a][a];
voidarr(a, arr1);
_arr(a, arr1, *pn1, *pn2, b, pb, 0);
larr(a, arr1, *pn1 + 1, *pn2, b, pb, 0);
for (; !(checkarr(a, arr1)); x++)
{
if ((x % 2) == 0)
{
_arr(a, arr1, *pn1, *pn2 - 1, b, pb, 1);
larr(a, arr1, *pn1 - 1, *pn2, b, pb, 1);
}
else if ((x % 2) == 1)
{
_arr(a, arr1, *pn1, *pn2 + 1, b, pb, 0);
larr(a, arr1, *pn1 + 1, *pn2, b, pb, 0);
}
}
printfarr(a, arr1);
return 0;
}
세줄 요약
1. 식에 +를 -로 써서 작동 안 했었음.
2. 내가 약간 더 최적화 시킴
3. 그래도 제법 잘 만든 코드였음.
-끝-
해당 댓글은 삭제되었습니다.
주말에 김장하고 오느라고 댓글이 달린 걸 이제야 알았네요. 1. 사실 답을 빨리 안주길래 뻗는다고 표현하긴 했지만, 단지 조금 많이 오래 걸릴 뿐 인건 지 메모리가 터진 건지, cpu가 터진건지는 잘 모릅니다. 사실 이미 4 자리 일 때 부터 (4^2)! 로 최종 계산값이 int로 표현 가능한 자리수 는 넘어가기 때문에 수가 너무 커지는 문제는 pc가 알아서 처리 했을 겁니다. 핵심은 굳이 전수조사 를 한다는 데 있습니다. 다음 질문의 답변도 될 텐데 어떤 계산을 하든 전수조사는 효율이 떨어집니다. 심지어 달팽이 모양 배열 채우기는 홀수 일 때 는 정 가운데, 짝수 일 때는 가운데에서 왼쪽 아래 숫자만 0 인지 a^2 인지만 체크하면 되는 문제인데 두 줄을 채울 때 마다 전수조사 시키는건
컴퓨터 라도 아마 귀찮을 겁니다. ㅋㅋㅋ 2. 위에서 말했듯 두 줄을 채울 때 마다 전수 조사 하는 게 마음에 안 들어서 바꿔봤습니다. 3. 아 쓰다보니 나중에 전역변수가 된 케이스 군요. 그럴 수 있습니다. 네넵, 보통 포인터를 쓰는 이유가 지역변수를 건들기 쉬우려고 쓰는데 전역변수에 왜 포인터가 있나 했었습니다. 4. 그냥 취향 문제 같습니다. 어쨌든 break; 를 써두면 컴퓨터가 보든 사람이 보든 반복문을 탈출한다는 게 직관적이니까요.
저도 6에서 멈추는 게 오버플로 가 문제인 줄만 알았는데 4x4 배열에서 부터 (4^2)! = 20,922,789,888,000 로 이미 최종 계산값 이 int의 최대값인 2,147,483,647 을 넘어가 버렸었습니다. 그럼에도 5 까지는 버텨준 것이 컴퓨터가 뭔가 알아서 처리해 준거 같다고 생각했습니다. 저도 잘은 모르겠네요 ㅋㅋㅋ