fork download
  1. /*
  2.  * We save the spiral in an n x n Matrix using a 2D array
  3.  * The number at coordinates (x, y) is in the x-th row and the y-th column
  4.  *
  5.  * / - - - y
  6.  * | 1 2 3 4
  7.  * | 12 13 14 5
  8.  * | 11 16 15 6
  9.  * x 10 9 8 7
  10.  *
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <stdbool.h>
  15. #include <math.h>
  16.  
  17. void print(int n, int spiral[n][n]) {
  18. int square = n * n;
  19.  
  20. int numDigits = floor(log10(square)) + 1;
  21.  
  22. for (int i = 0; i < n; ++i) {
  23. for (int j = 0; j < n; ++j) {
  24. printf("%*d ", numDigits, spiral[i][j]);
  25. }
  26. printf("\n");
  27. }
  28.  
  29. printf("\n");
  30. }
  31.  
  32. int main(int argc, char *argv[]) {
  33. bool reverse = argc > 1;
  34.  
  35. while(1) {
  36. int num = 0;
  37. scanf("%d", &num);
  38.  
  39. if(num <= 0) {
  40. // Abort on non positive numbers
  41. break;
  42. }
  43.  
  44. int spiral[num][num];
  45.  
  46. /*
  47.   * The coordinates in the spiral we are currently at
  48.   */
  49. int x = 0, y = 0;
  50.  
  51. /*
  52.   * For each number we travel on in the direction given by these two variables
  53.   * With these initial values we travel from the top left to the right
  54.   */
  55. int xDiff = 0;
  56. int yDiff = 1;
  57.  
  58. /*
  59.   * When walking the spiral this counts how many turns are left until we completed one layer of the spiral
  60.   * In the beginning there are three turns after that there are always two turns
  61.   */
  62. int turns = 3;
  63.  
  64. /*
  65.   * Length of edges in the current layer
  66.   * The number of steps we can take on an edge before we need to turn depends on what layer we are currently in
  67.   * in the beginning it is one less than the side length of the spiral and decreases by one for each layer
  68.   */
  69. int len = num - 1;
  70.  
  71. /*
  72.   * Counts how many steps we have remaining before we need to turn
  73.   */
  74. int lenRemaining = len;
  75.  
  76. for (int i = 1; i <= num * num; ++i) {
  77. /*
  78.   * Just in case
  79.   */
  80. if(x >= num || y >= num || x < 0 || y < 0) {
  81. fprintf(stderr, "An error occured while walking the spiral\n");
  82. continue;
  83. }
  84.  
  85. spiral[x][y] = i;
  86.  
  87. if(lenRemaining == 0) {
  88. /*
  89.   * We need to turn
  90.   */
  91.  
  92. turns--;
  93.  
  94. /*
  95.   * Set the new movement vectors
  96.   */
  97. int xDiffOld = xDiff;
  98. xDiff = yDiff;
  99. yDiff = -xDiffOld;
  100.  
  101. /*
  102.   * If we have no turns left, we have reached a new layer
  103.   */
  104. if(turns == 0) {
  105. len--;
  106. turns = 2;
  107. }
  108.  
  109. /*
  110.   * Reset lenRemaining
  111.   */
  112. lenRemaining = len;
  113. }
  114.  
  115. /*
  116.   * Apply movement vector and decrease remaining steps
  117.   */
  118. x += reverse? yDiff : xDiff;
  119. y += reverse? xDiff : yDiff;
  120. lenRemaining--;
  121. }
  122.  
  123. print(num, spiral);
  124. }
  125. return 0;
  126. }
Success #stdin #stdout 0s 9432KB
stdin
5
4
stdout
 1  2  3  4  5 
16 17 18 19  6 
15 24 25 20  7 
14 23 22 21  8 
13 12 11 10  9 

 1  2  3  4 
12 13 14  5 
11 16 15  6 
10  9  8  7