이렇게 재밌는 건 그냥 못 넘어간다. 여러가지 방법이 있겠지만 골치 아프게 엘리먼트의 위치에 따라 값을 계산하는 공식을 만드는 것보다는 그냥 둥글게 돌아다니면서 값을 채우는 게 제일 쉬운 것 같다.
$ 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로 개발한다면 테스트함수 만드는 게 더 귀찮을 것 같다. -.-;; 무식한 소리를 하는군...