이렇게 재밌는 건 그냥 못 넘어간다. 여러가지 방법이 있겠지만 골치 아프게 엘리먼트의 위치에 따라 값을 계산하는 공식을 만드는 것보다는 그냥 둥글게 돌아다니면서 값을 채우는 게 제일 쉬운 것 같다.
$ cat spiral_array.c #include <stdio.h> #include <stdlib.h> #include <math.h> int main(int argc, char *argv[]) { int i, j, k, l; int nrows, ncols, walk; int **array; printf("Spiral array generator using the walking pointer\n" "(C) 2007 GPL by Huidae Cho\n\n"); if(argc > 1) nrows = atoi(argv[1]); else do{ printf("nrows: "); scanf("%d", &nrows); }while(nrows <= 0); if(argc > 2) ncols = atoi(argv[2]); else do{ printf("ncols: "); scanf("%d", &ncols); }while(ncols <= 0); array = (int **)malloc(nrows*sizeof(int *)); for(i = 0; i < nrows; ++i){ array[i] = (int *)malloc(ncols*sizeof(int)); for(j = 0; j < ncols; ++j) array[i][j] = -1; } l = nrows*ncols; walk = 0; for(i = j = k = 0; k < l; ++k){ array[i][j] = k; switch(walk){ case 0: if(j < ncols-1 && array[i][j+1] == -1) ++j; else{ walk = 1; ++i; } break; case 1: if(i < nrows-1 && array[i+1][j] == -1) ++i; else{ walk = 2; --j; } break; case 2: if(j > 0 && array[i][j-1] == -1) --j; else{ walk = 3; --i; } break; case 3: if(i > 0 && array[i-1][j] == -1) --i; else{ walk = 0; ++j; } break; } } if(argc < 3) printf("\n"); l = (l == 1 ? 1 : (int)log10(l-1)+1) + 1; for(i = 0; i < nrows; ++i){ for(j = 0; j < ncols; ++j) printf("%*d", l, array[i][j]); printf("\n"); free(array[i]); } free(array); exit(EXIT_SUCCESS); }
테스트 해보자.
$ ./spiral_array 10 10 Spiral array generator using the walking pointer (C) 2007 GPL by Huidae Cho 0 1 2 3 4 5 6 7 8 9 35 36 37 38 39 40 41 42 43 10 34 63 64 65 66 67 68 69 44 11 33 62 83 84 85 86 87 70 45 12 32 61 82 95 96 97 88 71 46 13 31 60 81 94 99 98 89 72 47 14 30 59 80 93 92 91 90 73 48 15 29 58 79 78 77 76 75 74 49 16 28 57 56 55 54 53 52 51 50 17 27 26 25 24 23 22 21 20 19 18
그런데 이런 걸 Test-Driven Development로 개발한다면 테스트함수 만드는 게 더 귀찮을 것 같다. -.-;; 무식한 소리를 하는군...