what is the better way to loop this problem?









up vote
1
down vote

favorite
2












#include <stdio.h>

int main()

int arr[9][9];
int i = 0, x = 10;

for (int i = 0, j = 0; j <= 8; j++)
x++;
arr[i][j] = x;

for (int j = 8, i = 1; i <= 8; i++)
x++;
arr[i][j] = x;

for (int i = 8, j = 7; j >= 0; j--)
x++;
arr[i][j] = x;

for (int j = 0, i = 7; i >= 1; i--)
x++;
arr[i][j] = x;


for (int i = 1, j = 1; j <= 7; j++)
x++;
arr[i][j] = x;

for (int j = 7, i = 2; i <= 7; i++)
x++;
arr[i][j] = x;

for (int i = 7, j = 6; j >= 1; j--)
x++;
arr[i][j] = x;

for (int j = 1, i = 6; i >= 2; i--)
x++;
arr[i][j] = x;

...
arr[4][4] = x + 1;


for (int i = 0; i <= 8; i++)
for (int j = 0; j <= 8; j++)
printf("%d ", arr[i][j]);
printf("n");

getch();



so I have this program, and I know you can loop it but how ? been sitting for an hour thinking and nothing came to my mind. By the way, the task is to append a matrix like on picture. Does anyone know to do it ? Maybe use some complex for loopenter image description here










share|improve this question

















  • 1




    4 variables to keep track of the upper and lower boundaries for x and y directions. One big loop until they cross, containing 4 for loops (one per side). After each line along one side, adjust the boundary for that side.
    – Dmitri
    Nov 11 at 18:46










  • what's the point for using "variables" for constants in the loops?
    – Antti Haapala
    Nov 11 at 18:58






  • 2




    You don't need any for loops, just a while loop. Turn left whenever hitting the edge or an already filled position.
    – Antti Haapala
    Nov 11 at 19:00






  • 1




    @AnttiHaapala it needs to turn right, isn`t it ? But how do I do it ?
    – Степан Бандера
    Nov 11 at 19:04






  • 1




    Though it's possible to use a single while loop and no fors, keep in mind that that while would do many more iterations than any single for would have, and would need to test the movement direction and choose it's behaviour accordingly on every iteration. It's not objectively better than using for loops.
    – Dmitri
    Nov 11 at 19:09















up vote
1
down vote

favorite
2












#include <stdio.h>

int main()

int arr[9][9];
int i = 0, x = 10;

for (int i = 0, j = 0; j <= 8; j++)
x++;
arr[i][j] = x;

for (int j = 8, i = 1; i <= 8; i++)
x++;
arr[i][j] = x;

for (int i = 8, j = 7; j >= 0; j--)
x++;
arr[i][j] = x;

for (int j = 0, i = 7; i >= 1; i--)
x++;
arr[i][j] = x;


for (int i = 1, j = 1; j <= 7; j++)
x++;
arr[i][j] = x;

for (int j = 7, i = 2; i <= 7; i++)
x++;
arr[i][j] = x;

for (int i = 7, j = 6; j >= 1; j--)
x++;
arr[i][j] = x;

for (int j = 1, i = 6; i >= 2; i--)
x++;
arr[i][j] = x;

...
arr[4][4] = x + 1;


for (int i = 0; i <= 8; i++)
for (int j = 0; j <= 8; j++)
printf("%d ", arr[i][j]);
printf("n");

getch();



so I have this program, and I know you can loop it but how ? been sitting for an hour thinking and nothing came to my mind. By the way, the task is to append a matrix like on picture. Does anyone know to do it ? Maybe use some complex for loopenter image description here










share|improve this question

















  • 1




    4 variables to keep track of the upper and lower boundaries for x and y directions. One big loop until they cross, containing 4 for loops (one per side). After each line along one side, adjust the boundary for that side.
    – Dmitri
    Nov 11 at 18:46










  • what's the point for using "variables" for constants in the loops?
    – Antti Haapala
    Nov 11 at 18:58






  • 2




    You don't need any for loops, just a while loop. Turn left whenever hitting the edge or an already filled position.
    – Antti Haapala
    Nov 11 at 19:00






  • 1




    @AnttiHaapala it needs to turn right, isn`t it ? But how do I do it ?
    – Степан Бандера
    Nov 11 at 19:04






  • 1




    Though it's possible to use a single while loop and no fors, keep in mind that that while would do many more iterations than any single for would have, and would need to test the movement direction and choose it's behaviour accordingly on every iteration. It's not objectively better than using for loops.
    – Dmitri
    Nov 11 at 19:09













up vote
1
down vote

favorite
2









up vote
1
down vote

favorite
2






2





#include <stdio.h>

int main()

int arr[9][9];
int i = 0, x = 10;

for (int i = 0, j = 0; j <= 8; j++)
x++;
arr[i][j] = x;

for (int j = 8, i = 1; i <= 8; i++)
x++;
arr[i][j] = x;

for (int i = 8, j = 7; j >= 0; j--)
x++;
arr[i][j] = x;

for (int j = 0, i = 7; i >= 1; i--)
x++;
arr[i][j] = x;


for (int i = 1, j = 1; j <= 7; j++)
x++;
arr[i][j] = x;

for (int j = 7, i = 2; i <= 7; i++)
x++;
arr[i][j] = x;

for (int i = 7, j = 6; j >= 1; j--)
x++;
arr[i][j] = x;

for (int j = 1, i = 6; i >= 2; i--)
x++;
arr[i][j] = x;

...
arr[4][4] = x + 1;


for (int i = 0; i <= 8; i++)
for (int j = 0; j <= 8; j++)
printf("%d ", arr[i][j]);
printf("n");

getch();



so I have this program, and I know you can loop it but how ? been sitting for an hour thinking and nothing came to my mind. By the way, the task is to append a matrix like on picture. Does anyone know to do it ? Maybe use some complex for loopenter image description here










share|improve this question













#include <stdio.h>

int main()

int arr[9][9];
int i = 0, x = 10;

for (int i = 0, j = 0; j <= 8; j++)
x++;
arr[i][j] = x;

for (int j = 8, i = 1; i <= 8; i++)
x++;
arr[i][j] = x;

for (int i = 8, j = 7; j >= 0; j--)
x++;
arr[i][j] = x;

for (int j = 0, i = 7; i >= 1; i--)
x++;
arr[i][j] = x;


for (int i = 1, j = 1; j <= 7; j++)
x++;
arr[i][j] = x;

for (int j = 7, i = 2; i <= 7; i++)
x++;
arr[i][j] = x;

for (int i = 7, j = 6; j >= 1; j--)
x++;
arr[i][j] = x;

for (int j = 1, i = 6; i >= 2; i--)
x++;
arr[i][j] = x;

...
arr[4][4] = x + 1;


for (int i = 0; i <= 8; i++)
for (int j = 0; j <= 8; j++)
printf("%d ", arr[i][j]);
printf("n");

getch();



so I have this program, and I know you can loop it but how ? been sitting for an hour thinking and nothing came to my mind. By the way, the task is to append a matrix like on picture. Does anyone know to do it ? Maybe use some complex for loopenter image description here







c arrays matrix multidimensional-array






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 11 at 18:37









Степан Бандера

255




255







  • 1




    4 variables to keep track of the upper and lower boundaries for x and y directions. One big loop until they cross, containing 4 for loops (one per side). After each line along one side, adjust the boundary for that side.
    – Dmitri
    Nov 11 at 18:46










  • what's the point for using "variables" for constants in the loops?
    – Antti Haapala
    Nov 11 at 18:58






  • 2




    You don't need any for loops, just a while loop. Turn left whenever hitting the edge or an already filled position.
    – Antti Haapala
    Nov 11 at 19:00






  • 1




    @AnttiHaapala it needs to turn right, isn`t it ? But how do I do it ?
    – Степан Бандера
    Nov 11 at 19:04






  • 1




    Though it's possible to use a single while loop and no fors, keep in mind that that while would do many more iterations than any single for would have, and would need to test the movement direction and choose it's behaviour accordingly on every iteration. It's not objectively better than using for loops.
    – Dmitri
    Nov 11 at 19:09













  • 1




    4 variables to keep track of the upper and lower boundaries for x and y directions. One big loop until they cross, containing 4 for loops (one per side). After each line along one side, adjust the boundary for that side.
    – Dmitri
    Nov 11 at 18:46










  • what's the point for using "variables" for constants in the loops?
    – Antti Haapala
    Nov 11 at 18:58






  • 2




    You don't need any for loops, just a while loop. Turn left whenever hitting the edge or an already filled position.
    – Antti Haapala
    Nov 11 at 19:00






  • 1




    @AnttiHaapala it needs to turn right, isn`t it ? But how do I do it ?
    – Степан Бандера
    Nov 11 at 19:04






  • 1




    Though it's possible to use a single while loop and no fors, keep in mind that that while would do many more iterations than any single for would have, and would need to test the movement direction and choose it's behaviour accordingly on every iteration. It's not objectively better than using for loops.
    – Dmitri
    Nov 11 at 19:09








1




1




4 variables to keep track of the upper and lower boundaries for x and y directions. One big loop until they cross, containing 4 for loops (one per side). After each line along one side, adjust the boundary for that side.
– Dmitri
Nov 11 at 18:46




4 variables to keep track of the upper and lower boundaries for x and y directions. One big loop until they cross, containing 4 for loops (one per side). After each line along one side, adjust the boundary for that side.
– Dmitri
Nov 11 at 18:46












what's the point for using "variables" for constants in the loops?
– Antti Haapala
Nov 11 at 18:58




what's the point for using "variables" for constants in the loops?
– Antti Haapala
Nov 11 at 18:58




2




2




You don't need any for loops, just a while loop. Turn left whenever hitting the edge or an already filled position.
– Antti Haapala
Nov 11 at 19:00




You don't need any for loops, just a while loop. Turn left whenever hitting the edge or an already filled position.
– Antti Haapala
Nov 11 at 19:00




1




1




@AnttiHaapala it needs to turn right, isn`t it ? But how do I do it ?
– Степан Бандера
Nov 11 at 19:04




@AnttiHaapala it needs to turn right, isn`t it ? But how do I do it ?
– Степан Бандера
Nov 11 at 19:04




1




1




Though it's possible to use a single while loop and no fors, keep in mind that that while would do many more iterations than any single for would have, and would need to test the movement direction and choose it's behaviour accordingly on every iteration. It's not objectively better than using for loops.
– Dmitri
Nov 11 at 19:09





Though it's possible to use a single while loop and no fors, keep in mind that that while would do many more iterations than any single for would have, and would need to test the movement direction and choose it's behaviour accordingly on every iteration. It's not objectively better than using for loops.
– Dmitri
Nov 11 at 19:09













4 Answers
4






active

oldest

votes

















up vote
1
down vote



accepted










Here's one way to do it:



int arr[9][9] = 0;
int x = 0, i = 0, j = 0, vi = 0, vj = 1;

do
++x;
arr[i][j] = x;

jj >= 9

i = i+vi;
j = j+vj;
while (arr[i][j] == 0);


Live on Coliru



Here's another way:



int arr[9][9] = 0;
int x = 0, i = 0, j = 0, vi = 0, vj = 1, lk = 8;

while (lk > 0)
for (int k = 0; k < lk; ++k)
++x;
arr[i][j] = x;
i += vi;
j += vj;


vi = vj;
vj = 0;

for (int k = 0; k < lk; ++k)
++x;
arr[i][j] = x;
i += vi;
j += vj;


vj = -vi;
vi = 0;

if (vj > 0)
++i;
++j;
lk -= 2;



arr[9/2][9/2] = x+1; // Only if odd dimensions


Live on Coliru



And here is yet another:



int arr[9][9] = 0;
int i = 0, lk = 8, x = 1;

while (lk > 0)
for (int k = 0; k < lk; ++k)
arr[i][i+k] = x + k;
arr[i+k][lk+i] = x + lk + k;
arr[lk+i][lk+i-k] = x + 2*lk + k;
arr[lk+i-k][i] = x + 3*lk + k;


x += 4*lk;
lk -= 2;
++i;


arr[9/2][9/2] = x; // Only if odd dimensions


Live on Coliru






share|improve this answer






















  • it works perfectly ! but can you explain a bit what vi vj ii jj means ?
    – Степан Бандера
    Nov 11 at 19:30






  • 1




    vi and vj tell where you are currently going (think of it as a velocity vector); they are the increments for i and j. ii and jj are just temporaries.
    – Nelfeal
    Nov 11 at 19:32






  • 1




    This is one ugly code...
    – kfx
    Nov 11 at 19:35






  • 1




    @СтепанБандера i and j are positions. vi and vj are increments.
    – Nelfeal
    Nov 11 at 19:46






  • 1




    The third code builds the matrix "ring by ring", with the first ring containing all the values on the four edges. lk is the width of the current ring, minus one.
    – Nelfeal
    Nov 11 at 20:06

















up vote
1
down vote













Here is the "straight forward" option with for loops:



#include <stdio.h>

#define N 5

int main(void)
int i,j,dim;
int matrix[N][N];

// init and print the matrix
for (i=0; i < N; i++)

for (j=0; j< N; j++)

matrix[i][j] = i*N + j;
printf("%2d ", matrix[i][j]);

printf("n");


printf("n");

// perform spiral print
for (dim = 0; dim < (N+1)/2; dim++)

// set initial i and go till the "last column"
i = dim;
for (j = dim; j < N - dim; j++)

printf("%2d ", matrix[i][j]);

printf("n");

// bring back i and j to the proper coordinate
// and move down to the "last row"
j--;i++;
for (; i < N - dim; i++)

printf("%2d ", matrix[i][j]);

printf("n");

// bring back i and j to the proper coordinate
// and move back to the "first column"
i--;j--;
for (; j >= dim; j--)

printf("%2d ", matrix[i][j]);

printf("n");

// bring back i and j to the proper coordinate
// and move up to the "first row"
j++;i--;
for (; i > dim; i--)

printf("%2d ", matrix[i][j]);

printf("n");


return 0;



The output, as can be seen here is



 0 1 2 3 4 
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24

0 1 2 3 4
9 14 19 24
23 22 21 20
15 10 5
6 7 8
13 18
17 16
11
12


==========================================================================



Looks like I misunderstood the question but the step from "printing" clockwise to "setting" clockwise is really small. Here is the setting flow:



#include <stdio.h>

#define N 5

int main(void)
int i,j,dim, val = 1;
int matrix[N][N];

// perform spiral print
for (dim = 0; dim < (N+1)/2; dim++)

// set initial i and go till the "last column"
i = dim;
for (j = dim; j < N - dim; j++)

matrix[i][j] = val++;


// bring back i and j to the proper coordinate
// and move down to the "last row"
j--;i++;
for (; i < N - dim; i++)

matrix[i][j] = val++;


// bring back i and j to the proper coordinate
// and move back to the "first column"
i--;j--;
for (; j >= dim; j--)

matrix[i][j] = val++;


// bring back i and j to the proper coordinate
// and move up to the "first row"
j++;i--;
for (; i > dim; i--)

matrix[i][j] = val++;



// print the matrix
for (i=0; i < N; i++)

for (j=0; j< N; j++)

printf("%2d ", matrix[i][j]);

printf("n");


return 0;



The output as shown here is



 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





share|improve this answer






















  • it works like this ------> <------, but it needs to do it clockwise :(
    – Степан Бандера
    Nov 11 at 19:41






  • 1




    @СтепанБандераIt works clockwise: (right) 0-->4, (down) 9-->24, (left) 23-->20, (up) 15-->5, etc.
    – Alex Lop.
    Nov 11 at 19:43










  • @СтепанБандера The first print that you see is just the matrix initialization, then you see the "clockwise" print
    – Alex Lop.
    Nov 11 at 19:45







  • 1




    @СтепанБандера Hopefully this time I added the answer as you meant it (see the bottom part).
    – Alex Lop.
    Nov 11 at 20:10






  • 1




    @СтепанБандера You are welcome and good luck!
    – Alex Lop.
    Nov 11 at 20:14

















up vote
0
down vote













My solution. Using an "object" struct strangeite_s (from strange ite-rator). It allows ease reusing on different arrays and probably could be even rescaled to support n-dimensional arrays.

The strangeite is initialized using _init function with specified dimensions sizes of an 2d array. Each time _loop is evaluated, the x and y positions are updated and the condition for loop end is checked (and returned). The _inc function should be called on each increment of the iterator.



#include <stdio.h>
#include <limits.h>
#include <stddef.h>
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>

struct strangeite_s
size_t steplen[2];
size_t idx[2];
size_t cursteplen;
int direction;
;

void strangeite_init(struct strangeite_s *t, size_t max_x, size_t max_y)

assert(t != NULL);
t->steplen[0] = max_y;
t->steplen[1] = max_x;
memset(t->idx, 0, sizeof(t->idx));
t->direction = 0;
t->cursteplen = t->steplen[0];


bool strangeite_loop(const struct strangeite_s *t, size_t *x, size_t *y)

if (x) *x = t->idx[0];
if (y) *y = t->idx[1];
for (size_t i = 0; i < sizeof(t->steplen)/sizeof(t->steplen[0]); ++i)
if (t->steplen[i] == 0)
return false;


return true;


void strangeite_inc(struct strangeite_s *t)

if (t->cursteplen != 1)
--t->cursteplen;
else
t->direction = ++t->direction % (2 * 2);
t->cursteplen = --t->steplen[t->direction % 2];

const size_t idx_to_change = t->direction % 2;
t->idx[idx_to_change] = t->idx[idx_to_change] + ( t->direction < 2 ? +1 : -1 );


int main()

int var[5][5];

struct strangeite_s i;
strangeite_init(&i, 5, 5);
int idx = 0;
for (size_t x, y; strangeite_loop(&i, &x, &y); strangeite_inc(&i))
var[y][x] = ++idx;


for (size_t i = 0; i < 5; ++i)
for (size_t j = 0; j < 5; ++j)
printf("%d ", var[i][j]);

printf("n");


return 0;



Produces the following output:



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


Live version at onlinegdb.






share|improve this answer



























    up vote
    0
    down vote













    It's possible to deterministically compute any one entry in the array A_i,j as a function only given the array size N, and i, j, in O(1), on-line, without any state, noticing the radius is a geometric progression. The space requirement is O(1) since one doesn't actually need the array to store the values; we can scan the array sequentially. However, like ray-tracing, it probably is slower, (up to a constant, it's still O(N^2).)



    #include <stdio.h>

    /* N: The size of the (simulated) array. */
    #define N (16)

    /* i, j: The array indices, as if, a[i][j]. */
    static int a(const int i, const int j)
    /* (x,y) translation of (i,-j) to the centre, scaled up 2x for int math. */
    const int x = 2 * i + 1 - N, y = -2 * j - 1 + N;
    /* Geometric series and an offset +fiddling to get the directionality. */
    return N*N - ((x < -y) ?
    (-x > -y) ? (x+1)*(x+1) - (y+x)/2 - 1: y*y + (x+y)/2 :
    (x > y) ? x*x + (x+y)/2 : (y+1)*y + (-x+y)/2);


    int main(void)
    int i, j;
    for(j = 0; j < N; j++)
    for(i = 0; i < N; i++)
    printf("%3d ", a(i, j));

    printf("n");

    return 0;






    share|improve this answer






















      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53251914%2fwhat-is-the-better-way-to-loop-this-problem%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      1
      down vote



      accepted










      Here's one way to do it:



      int arr[9][9] = 0;
      int x = 0, i = 0, j = 0, vi = 0, vj = 1;

      do
      ++x;
      arr[i][j] = x;

      jj >= 9

      i = i+vi;
      j = j+vj;
      while (arr[i][j] == 0);


      Live on Coliru



      Here's another way:



      int arr[9][9] = 0;
      int x = 0, i = 0, j = 0, vi = 0, vj = 1, lk = 8;

      while (lk > 0)
      for (int k = 0; k < lk; ++k)
      ++x;
      arr[i][j] = x;
      i += vi;
      j += vj;


      vi = vj;
      vj = 0;

      for (int k = 0; k < lk; ++k)
      ++x;
      arr[i][j] = x;
      i += vi;
      j += vj;


      vj = -vi;
      vi = 0;

      if (vj > 0)
      ++i;
      ++j;
      lk -= 2;



      arr[9/2][9/2] = x+1; // Only if odd dimensions


      Live on Coliru



      And here is yet another:



      int arr[9][9] = 0;
      int i = 0, lk = 8, x = 1;

      while (lk > 0)
      for (int k = 0; k < lk; ++k)
      arr[i][i+k] = x + k;
      arr[i+k][lk+i] = x + lk + k;
      arr[lk+i][lk+i-k] = x + 2*lk + k;
      arr[lk+i-k][i] = x + 3*lk + k;


      x += 4*lk;
      lk -= 2;
      ++i;


      arr[9/2][9/2] = x; // Only if odd dimensions


      Live on Coliru






      share|improve this answer






















      • it works perfectly ! but can you explain a bit what vi vj ii jj means ?
        – Степан Бандера
        Nov 11 at 19:30






      • 1




        vi and vj tell where you are currently going (think of it as a velocity vector); they are the increments for i and j. ii and jj are just temporaries.
        – Nelfeal
        Nov 11 at 19:32






      • 1




        This is one ugly code...
        – kfx
        Nov 11 at 19:35






      • 1




        @СтепанБандера i and j are positions. vi and vj are increments.
        – Nelfeal
        Nov 11 at 19:46






      • 1




        The third code builds the matrix "ring by ring", with the first ring containing all the values on the four edges. lk is the width of the current ring, minus one.
        – Nelfeal
        Nov 11 at 20:06














      up vote
      1
      down vote



      accepted










      Here's one way to do it:



      int arr[9][9] = 0;
      int x = 0, i = 0, j = 0, vi = 0, vj = 1;

      do
      ++x;
      arr[i][j] = x;

      jj >= 9

      i = i+vi;
      j = j+vj;
      while (arr[i][j] == 0);


      Live on Coliru



      Here's another way:



      int arr[9][9] = 0;
      int x = 0, i = 0, j = 0, vi = 0, vj = 1, lk = 8;

      while (lk > 0)
      for (int k = 0; k < lk; ++k)
      ++x;
      arr[i][j] = x;
      i += vi;
      j += vj;


      vi = vj;
      vj = 0;

      for (int k = 0; k < lk; ++k)
      ++x;
      arr[i][j] = x;
      i += vi;
      j += vj;


      vj = -vi;
      vi = 0;

      if (vj > 0)
      ++i;
      ++j;
      lk -= 2;



      arr[9/2][9/2] = x+1; // Only if odd dimensions


      Live on Coliru



      And here is yet another:



      int arr[9][9] = 0;
      int i = 0, lk = 8, x = 1;

      while (lk > 0)
      for (int k = 0; k < lk; ++k)
      arr[i][i+k] = x + k;
      arr[i+k][lk+i] = x + lk + k;
      arr[lk+i][lk+i-k] = x + 2*lk + k;
      arr[lk+i-k][i] = x + 3*lk + k;


      x += 4*lk;
      lk -= 2;
      ++i;


      arr[9/2][9/2] = x; // Only if odd dimensions


      Live on Coliru






      share|improve this answer






















      • it works perfectly ! but can you explain a bit what vi vj ii jj means ?
        – Степан Бандера
        Nov 11 at 19:30






      • 1




        vi and vj tell where you are currently going (think of it as a velocity vector); they are the increments for i and j. ii and jj are just temporaries.
        – Nelfeal
        Nov 11 at 19:32






      • 1




        This is one ugly code...
        – kfx
        Nov 11 at 19:35






      • 1




        @СтепанБандера i and j are positions. vi and vj are increments.
        – Nelfeal
        Nov 11 at 19:46






      • 1




        The third code builds the matrix "ring by ring", with the first ring containing all the values on the four edges. lk is the width of the current ring, minus one.
        – Nelfeal
        Nov 11 at 20:06












      up vote
      1
      down vote



      accepted







      up vote
      1
      down vote



      accepted






      Here's one way to do it:



      int arr[9][9] = 0;
      int x = 0, i = 0, j = 0, vi = 0, vj = 1;

      do
      ++x;
      arr[i][j] = x;

      jj >= 9

      i = i+vi;
      j = j+vj;
      while (arr[i][j] == 0);


      Live on Coliru



      Here's another way:



      int arr[9][9] = 0;
      int x = 0, i = 0, j = 0, vi = 0, vj = 1, lk = 8;

      while (lk > 0)
      for (int k = 0; k < lk; ++k)
      ++x;
      arr[i][j] = x;
      i += vi;
      j += vj;


      vi = vj;
      vj = 0;

      for (int k = 0; k < lk; ++k)
      ++x;
      arr[i][j] = x;
      i += vi;
      j += vj;


      vj = -vi;
      vi = 0;

      if (vj > 0)
      ++i;
      ++j;
      lk -= 2;



      arr[9/2][9/2] = x+1; // Only if odd dimensions


      Live on Coliru



      And here is yet another:



      int arr[9][9] = 0;
      int i = 0, lk = 8, x = 1;

      while (lk > 0)
      for (int k = 0; k < lk; ++k)
      arr[i][i+k] = x + k;
      arr[i+k][lk+i] = x + lk + k;
      arr[lk+i][lk+i-k] = x + 2*lk + k;
      arr[lk+i-k][i] = x + 3*lk + k;


      x += 4*lk;
      lk -= 2;
      ++i;


      arr[9/2][9/2] = x; // Only if odd dimensions


      Live on Coliru






      share|improve this answer














      Here's one way to do it:



      int arr[9][9] = 0;
      int x = 0, i = 0, j = 0, vi = 0, vj = 1;

      do
      ++x;
      arr[i][j] = x;

      jj >= 9

      i = i+vi;
      j = j+vj;
      while (arr[i][j] == 0);


      Live on Coliru



      Here's another way:



      int arr[9][9] = 0;
      int x = 0, i = 0, j = 0, vi = 0, vj = 1, lk = 8;

      while (lk > 0)
      for (int k = 0; k < lk; ++k)
      ++x;
      arr[i][j] = x;
      i += vi;
      j += vj;


      vi = vj;
      vj = 0;

      for (int k = 0; k < lk; ++k)
      ++x;
      arr[i][j] = x;
      i += vi;
      j += vj;


      vj = -vi;
      vi = 0;

      if (vj > 0)
      ++i;
      ++j;
      lk -= 2;



      arr[9/2][9/2] = x+1; // Only if odd dimensions


      Live on Coliru



      And here is yet another:



      int arr[9][9] = 0;
      int i = 0, lk = 8, x = 1;

      while (lk > 0)
      for (int k = 0; k < lk; ++k)
      arr[i][i+k] = x + k;
      arr[i+k][lk+i] = x + lk + k;
      arr[lk+i][lk+i-k] = x + 2*lk + k;
      arr[lk+i-k][i] = x + 3*lk + k;


      x += 4*lk;
      lk -= 2;
      ++i;


      arr[9/2][9/2] = x; // Only if odd dimensions


      Live on Coliru







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 11 at 19:42

























      answered Nov 11 at 19:17









      Nelfeal

      4,060621




      4,060621











      • it works perfectly ! but can you explain a bit what vi vj ii jj means ?
        – Степан Бандера
        Nov 11 at 19:30






      • 1




        vi and vj tell where you are currently going (think of it as a velocity vector); they are the increments for i and j. ii and jj are just temporaries.
        – Nelfeal
        Nov 11 at 19:32






      • 1




        This is one ugly code...
        – kfx
        Nov 11 at 19:35






      • 1




        @СтепанБандера i and j are positions. vi and vj are increments.
        – Nelfeal
        Nov 11 at 19:46






      • 1




        The third code builds the matrix "ring by ring", with the first ring containing all the values on the four edges. lk is the width of the current ring, minus one.
        – Nelfeal
        Nov 11 at 20:06
















      • it works perfectly ! but can you explain a bit what vi vj ii jj means ?
        – Степан Бандера
        Nov 11 at 19:30






      • 1




        vi and vj tell where you are currently going (think of it as a velocity vector); they are the increments for i and j. ii and jj are just temporaries.
        – Nelfeal
        Nov 11 at 19:32






      • 1




        This is one ugly code...
        – kfx
        Nov 11 at 19:35






      • 1




        @СтепанБандера i and j are positions. vi and vj are increments.
        – Nelfeal
        Nov 11 at 19:46






      • 1




        The third code builds the matrix "ring by ring", with the first ring containing all the values on the four edges. lk is the width of the current ring, minus one.
        – Nelfeal
        Nov 11 at 20:06















      it works perfectly ! but can you explain a bit what vi vj ii jj means ?
      – Степан Бандера
      Nov 11 at 19:30




      it works perfectly ! but can you explain a bit what vi vj ii jj means ?
      – Степан Бандера
      Nov 11 at 19:30




      1




      1




      vi and vj tell where you are currently going (think of it as a velocity vector); they are the increments for i and j. ii and jj are just temporaries.
      – Nelfeal
      Nov 11 at 19:32




      vi and vj tell where you are currently going (think of it as a velocity vector); they are the increments for i and j. ii and jj are just temporaries.
      – Nelfeal
      Nov 11 at 19:32




      1




      1




      This is one ugly code...
      – kfx
      Nov 11 at 19:35




      This is one ugly code...
      – kfx
      Nov 11 at 19:35




      1




      1




      @СтепанБандера i and j are positions. vi and vj are increments.
      – Nelfeal
      Nov 11 at 19:46




      @СтепанБандера i and j are positions. vi and vj are increments.
      – Nelfeal
      Nov 11 at 19:46




      1




      1




      The third code builds the matrix "ring by ring", with the first ring containing all the values on the four edges. lk is the width of the current ring, minus one.
      – Nelfeal
      Nov 11 at 20:06




      The third code builds the matrix "ring by ring", with the first ring containing all the values on the four edges. lk is the width of the current ring, minus one.
      – Nelfeal
      Nov 11 at 20:06












      up vote
      1
      down vote













      Here is the "straight forward" option with for loops:



      #include <stdio.h>

      #define N 5

      int main(void)
      int i,j,dim;
      int matrix[N][N];

      // init and print the matrix
      for (i=0; i < N; i++)

      for (j=0; j< N; j++)

      matrix[i][j] = i*N + j;
      printf("%2d ", matrix[i][j]);

      printf("n");


      printf("n");

      // perform spiral print
      for (dim = 0; dim < (N+1)/2; dim++)

      // set initial i and go till the "last column"
      i = dim;
      for (j = dim; j < N - dim; j++)

      printf("%2d ", matrix[i][j]);

      printf("n");

      // bring back i and j to the proper coordinate
      // and move down to the "last row"
      j--;i++;
      for (; i < N - dim; i++)

      printf("%2d ", matrix[i][j]);

      printf("n");

      // bring back i and j to the proper coordinate
      // and move back to the "first column"
      i--;j--;
      for (; j >= dim; j--)

      printf("%2d ", matrix[i][j]);

      printf("n");

      // bring back i and j to the proper coordinate
      // and move up to the "first row"
      j++;i--;
      for (; i > dim; i--)

      printf("%2d ", matrix[i][j]);

      printf("n");


      return 0;



      The output, as can be seen here is



       0 1 2 3 4 
      5 6 7 8 9
      10 11 12 13 14
      15 16 17 18 19
      20 21 22 23 24

      0 1 2 3 4
      9 14 19 24
      23 22 21 20
      15 10 5
      6 7 8
      13 18
      17 16
      11
      12


      ==========================================================================



      Looks like I misunderstood the question but the step from "printing" clockwise to "setting" clockwise is really small. Here is the setting flow:



      #include <stdio.h>

      #define N 5

      int main(void)
      int i,j,dim, val = 1;
      int matrix[N][N];

      // perform spiral print
      for (dim = 0; dim < (N+1)/2; dim++)

      // set initial i and go till the "last column"
      i = dim;
      for (j = dim; j < N - dim; j++)

      matrix[i][j] = val++;


      // bring back i and j to the proper coordinate
      // and move down to the "last row"
      j--;i++;
      for (; i < N - dim; i++)

      matrix[i][j] = val++;


      // bring back i and j to the proper coordinate
      // and move back to the "first column"
      i--;j--;
      for (; j >= dim; j--)

      matrix[i][j] = val++;


      // bring back i and j to the proper coordinate
      // and move up to the "first row"
      j++;i--;
      for (; i > dim; i--)

      matrix[i][j] = val++;



      // print the matrix
      for (i=0; i < N; i++)

      for (j=0; j< N; j++)

      printf("%2d ", matrix[i][j]);

      printf("n");


      return 0;



      The output as shown here is



       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





      share|improve this answer






















      • it works like this ------> <------, but it needs to do it clockwise :(
        – Степан Бандера
        Nov 11 at 19:41






      • 1




        @СтепанБандераIt works clockwise: (right) 0-->4, (down) 9-->24, (left) 23-->20, (up) 15-->5, etc.
        – Alex Lop.
        Nov 11 at 19:43










      • @СтепанБандера The first print that you see is just the matrix initialization, then you see the "clockwise" print
        – Alex Lop.
        Nov 11 at 19:45







      • 1




        @СтепанБандера Hopefully this time I added the answer as you meant it (see the bottom part).
        – Alex Lop.
        Nov 11 at 20:10






      • 1




        @СтепанБандера You are welcome and good luck!
        – Alex Lop.
        Nov 11 at 20:14














      up vote
      1
      down vote













      Here is the "straight forward" option with for loops:



      #include <stdio.h>

      #define N 5

      int main(void)
      int i,j,dim;
      int matrix[N][N];

      // init and print the matrix
      for (i=0; i < N; i++)

      for (j=0; j< N; j++)

      matrix[i][j] = i*N + j;
      printf("%2d ", matrix[i][j]);

      printf("n");


      printf("n");

      // perform spiral print
      for (dim = 0; dim < (N+1)/2; dim++)

      // set initial i and go till the "last column"
      i = dim;
      for (j = dim; j < N - dim; j++)

      printf("%2d ", matrix[i][j]);

      printf("n");

      // bring back i and j to the proper coordinate
      // and move down to the "last row"
      j--;i++;
      for (; i < N - dim; i++)

      printf("%2d ", matrix[i][j]);

      printf("n");

      // bring back i and j to the proper coordinate
      // and move back to the "first column"
      i--;j--;
      for (; j >= dim; j--)

      printf("%2d ", matrix[i][j]);

      printf("n");

      // bring back i and j to the proper coordinate
      // and move up to the "first row"
      j++;i--;
      for (; i > dim; i--)

      printf("%2d ", matrix[i][j]);

      printf("n");


      return 0;



      The output, as can be seen here is



       0 1 2 3 4 
      5 6 7 8 9
      10 11 12 13 14
      15 16 17 18 19
      20 21 22 23 24

      0 1 2 3 4
      9 14 19 24
      23 22 21 20
      15 10 5
      6 7 8
      13 18
      17 16
      11
      12


      ==========================================================================



      Looks like I misunderstood the question but the step from "printing" clockwise to "setting" clockwise is really small. Here is the setting flow:



      #include <stdio.h>

      #define N 5

      int main(void)
      int i,j,dim, val = 1;
      int matrix[N][N];

      // perform spiral print
      for (dim = 0; dim < (N+1)/2; dim++)

      // set initial i and go till the "last column"
      i = dim;
      for (j = dim; j < N - dim; j++)

      matrix[i][j] = val++;


      // bring back i and j to the proper coordinate
      // and move down to the "last row"
      j--;i++;
      for (; i < N - dim; i++)

      matrix[i][j] = val++;


      // bring back i and j to the proper coordinate
      // and move back to the "first column"
      i--;j--;
      for (; j >= dim; j--)

      matrix[i][j] = val++;


      // bring back i and j to the proper coordinate
      // and move up to the "first row"
      j++;i--;
      for (; i > dim; i--)

      matrix[i][j] = val++;



      // print the matrix
      for (i=0; i < N; i++)

      for (j=0; j< N; j++)

      printf("%2d ", matrix[i][j]);

      printf("n");


      return 0;



      The output as shown here is



       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





      share|improve this answer






















      • it works like this ------> <------, but it needs to do it clockwise :(
        – Степан Бандера
        Nov 11 at 19:41






      • 1




        @СтепанБандераIt works clockwise: (right) 0-->4, (down) 9-->24, (left) 23-->20, (up) 15-->5, etc.
        – Alex Lop.
        Nov 11 at 19:43










      • @СтепанБандера The first print that you see is just the matrix initialization, then you see the "clockwise" print
        – Alex Lop.
        Nov 11 at 19:45







      • 1




        @СтепанБандера Hopefully this time I added the answer as you meant it (see the bottom part).
        – Alex Lop.
        Nov 11 at 20:10






      • 1




        @СтепанБандера You are welcome and good luck!
        – Alex Lop.
        Nov 11 at 20:14












      up vote
      1
      down vote










      up vote
      1
      down vote









      Here is the "straight forward" option with for loops:



      #include <stdio.h>

      #define N 5

      int main(void)
      int i,j,dim;
      int matrix[N][N];

      // init and print the matrix
      for (i=0; i < N; i++)

      for (j=0; j< N; j++)

      matrix[i][j] = i*N + j;
      printf("%2d ", matrix[i][j]);

      printf("n");


      printf("n");

      // perform spiral print
      for (dim = 0; dim < (N+1)/2; dim++)

      // set initial i and go till the "last column"
      i = dim;
      for (j = dim; j < N - dim; j++)

      printf("%2d ", matrix[i][j]);

      printf("n");

      // bring back i and j to the proper coordinate
      // and move down to the "last row"
      j--;i++;
      for (; i < N - dim; i++)

      printf("%2d ", matrix[i][j]);

      printf("n");

      // bring back i and j to the proper coordinate
      // and move back to the "first column"
      i--;j--;
      for (; j >= dim; j--)

      printf("%2d ", matrix[i][j]);

      printf("n");

      // bring back i and j to the proper coordinate
      // and move up to the "first row"
      j++;i--;
      for (; i > dim; i--)

      printf("%2d ", matrix[i][j]);

      printf("n");


      return 0;



      The output, as can be seen here is



       0 1 2 3 4 
      5 6 7 8 9
      10 11 12 13 14
      15 16 17 18 19
      20 21 22 23 24

      0 1 2 3 4
      9 14 19 24
      23 22 21 20
      15 10 5
      6 7 8
      13 18
      17 16
      11
      12


      ==========================================================================



      Looks like I misunderstood the question but the step from "printing" clockwise to "setting" clockwise is really small. Here is the setting flow:



      #include <stdio.h>

      #define N 5

      int main(void)
      int i,j,dim, val = 1;
      int matrix[N][N];

      // perform spiral print
      for (dim = 0; dim < (N+1)/2; dim++)

      // set initial i and go till the "last column"
      i = dim;
      for (j = dim; j < N - dim; j++)

      matrix[i][j] = val++;


      // bring back i and j to the proper coordinate
      // and move down to the "last row"
      j--;i++;
      for (; i < N - dim; i++)

      matrix[i][j] = val++;


      // bring back i and j to the proper coordinate
      // and move back to the "first column"
      i--;j--;
      for (; j >= dim; j--)

      matrix[i][j] = val++;


      // bring back i and j to the proper coordinate
      // and move up to the "first row"
      j++;i--;
      for (; i > dim; i--)

      matrix[i][j] = val++;



      // print the matrix
      for (i=0; i < N; i++)

      for (j=0; j< N; j++)

      printf("%2d ", matrix[i][j]);

      printf("n");


      return 0;



      The output as shown here is



       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





      share|improve this answer














      Here is the "straight forward" option with for loops:



      #include <stdio.h>

      #define N 5

      int main(void)
      int i,j,dim;
      int matrix[N][N];

      // init and print the matrix
      for (i=0; i < N; i++)

      for (j=0; j< N; j++)

      matrix[i][j] = i*N + j;
      printf("%2d ", matrix[i][j]);

      printf("n");


      printf("n");

      // perform spiral print
      for (dim = 0; dim < (N+1)/2; dim++)

      // set initial i and go till the "last column"
      i = dim;
      for (j = dim; j < N - dim; j++)

      printf("%2d ", matrix[i][j]);

      printf("n");

      // bring back i and j to the proper coordinate
      // and move down to the "last row"
      j--;i++;
      for (; i < N - dim; i++)

      printf("%2d ", matrix[i][j]);

      printf("n");

      // bring back i and j to the proper coordinate
      // and move back to the "first column"
      i--;j--;
      for (; j >= dim; j--)

      printf("%2d ", matrix[i][j]);

      printf("n");

      // bring back i and j to the proper coordinate
      // and move up to the "first row"
      j++;i--;
      for (; i > dim; i--)

      printf("%2d ", matrix[i][j]);

      printf("n");


      return 0;



      The output, as can be seen here is



       0 1 2 3 4 
      5 6 7 8 9
      10 11 12 13 14
      15 16 17 18 19
      20 21 22 23 24

      0 1 2 3 4
      9 14 19 24
      23 22 21 20
      15 10 5
      6 7 8
      13 18
      17 16
      11
      12


      ==========================================================================



      Looks like I misunderstood the question but the step from "printing" clockwise to "setting" clockwise is really small. Here is the setting flow:



      #include <stdio.h>

      #define N 5

      int main(void)
      int i,j,dim, val = 1;
      int matrix[N][N];

      // perform spiral print
      for (dim = 0; dim < (N+1)/2; dim++)

      // set initial i and go till the "last column"
      i = dim;
      for (j = dim; j < N - dim; j++)

      matrix[i][j] = val++;


      // bring back i and j to the proper coordinate
      // and move down to the "last row"
      j--;i++;
      for (; i < N - dim; i++)

      matrix[i][j] = val++;


      // bring back i and j to the proper coordinate
      // and move back to the "first column"
      i--;j--;
      for (; j >= dim; j--)

      matrix[i][j] = val++;


      // bring back i and j to the proper coordinate
      // and move up to the "first row"
      j++;i--;
      for (; i > dim; i--)

      matrix[i][j] = val++;



      // print the matrix
      for (i=0; i < N; i++)

      for (j=0; j< N; j++)

      printf("%2d ", matrix[i][j]);

      printf("n");


      return 0;



      The output as shown here is



       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






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 11 at 20:09

























      answered Nov 11 at 19:34









      Alex Lop.

      4,38111332




      4,38111332











      • it works like this ------> <------, but it needs to do it clockwise :(
        – Степан Бандера
        Nov 11 at 19:41






      • 1




        @СтепанБандераIt works clockwise: (right) 0-->4, (down) 9-->24, (left) 23-->20, (up) 15-->5, etc.
        – Alex Lop.
        Nov 11 at 19:43










      • @СтепанБандера The first print that you see is just the matrix initialization, then you see the "clockwise" print
        – Alex Lop.
        Nov 11 at 19:45







      • 1




        @СтепанБандера Hopefully this time I added the answer as you meant it (see the bottom part).
        – Alex Lop.
        Nov 11 at 20:10






      • 1




        @СтепанБандера You are welcome and good luck!
        – Alex Lop.
        Nov 11 at 20:14
















      • it works like this ------> <------, but it needs to do it clockwise :(
        – Степан Бандера
        Nov 11 at 19:41






      • 1




        @СтепанБандераIt works clockwise: (right) 0-->4, (down) 9-->24, (left) 23-->20, (up) 15-->5, etc.
        – Alex Lop.
        Nov 11 at 19:43










      • @СтепанБандера The first print that you see is just the matrix initialization, then you see the "clockwise" print
        – Alex Lop.
        Nov 11 at 19:45







      • 1




        @СтепанБандера Hopefully this time I added the answer as you meant it (see the bottom part).
        – Alex Lop.
        Nov 11 at 20:10






      • 1




        @СтепанБандера You are welcome and good luck!
        – Alex Lop.
        Nov 11 at 20:14















      it works like this ------> <------, but it needs to do it clockwise :(
      – Степан Бандера
      Nov 11 at 19:41




      it works like this ------> <------, but it needs to do it clockwise :(
      – Степан Бандера
      Nov 11 at 19:41




      1




      1




      @СтепанБандераIt works clockwise: (right) 0-->4, (down) 9-->24, (left) 23-->20, (up) 15-->5, etc.
      – Alex Lop.
      Nov 11 at 19:43




      @СтепанБандераIt works clockwise: (right) 0-->4, (down) 9-->24, (left) 23-->20, (up) 15-->5, etc.
      – Alex Lop.
      Nov 11 at 19:43












      @СтепанБандера The first print that you see is just the matrix initialization, then you see the "clockwise" print
      – Alex Lop.
      Nov 11 at 19:45





      @СтепанБандера The first print that you see is just the matrix initialization, then you see the "clockwise" print
      – Alex Lop.
      Nov 11 at 19:45





      1




      1




      @СтепанБандера Hopefully this time I added the answer as you meant it (see the bottom part).
      – Alex Lop.
      Nov 11 at 20:10




      @СтепанБандера Hopefully this time I added the answer as you meant it (see the bottom part).
      – Alex Lop.
      Nov 11 at 20:10




      1




      1




      @СтепанБандера You are welcome and good luck!
      – Alex Lop.
      Nov 11 at 20:14




      @СтепанБандера You are welcome and good luck!
      – Alex Lop.
      Nov 11 at 20:14










      up vote
      0
      down vote













      My solution. Using an "object" struct strangeite_s (from strange ite-rator). It allows ease reusing on different arrays and probably could be even rescaled to support n-dimensional arrays.

      The strangeite is initialized using _init function with specified dimensions sizes of an 2d array. Each time _loop is evaluated, the x and y positions are updated and the condition for loop end is checked (and returned). The _inc function should be called on each increment of the iterator.



      #include <stdio.h>
      #include <limits.h>
      #include <stddef.h>
      #include <assert.h>
      #include <stdint.h>
      #include <string.h>
      #include <stdbool.h>

      struct strangeite_s
      size_t steplen[2];
      size_t idx[2];
      size_t cursteplen;
      int direction;
      ;

      void strangeite_init(struct strangeite_s *t, size_t max_x, size_t max_y)

      assert(t != NULL);
      t->steplen[0] = max_y;
      t->steplen[1] = max_x;
      memset(t->idx, 0, sizeof(t->idx));
      t->direction = 0;
      t->cursteplen = t->steplen[0];


      bool strangeite_loop(const struct strangeite_s *t, size_t *x, size_t *y)

      if (x) *x = t->idx[0];
      if (y) *y = t->idx[1];
      for (size_t i = 0; i < sizeof(t->steplen)/sizeof(t->steplen[0]); ++i)
      if (t->steplen[i] == 0)
      return false;


      return true;


      void strangeite_inc(struct strangeite_s *t)

      if (t->cursteplen != 1)
      --t->cursteplen;
      else
      t->direction = ++t->direction % (2 * 2);
      t->cursteplen = --t->steplen[t->direction % 2];

      const size_t idx_to_change = t->direction % 2;
      t->idx[idx_to_change] = t->idx[idx_to_change] + ( t->direction < 2 ? +1 : -1 );


      int main()

      int var[5][5];

      struct strangeite_s i;
      strangeite_init(&i, 5, 5);
      int idx = 0;
      for (size_t x, y; strangeite_loop(&i, &x, &y); strangeite_inc(&i))
      var[y][x] = ++idx;


      for (size_t i = 0; i < 5; ++i)
      for (size_t j = 0; j < 5; ++j)
      printf("%d ", var[i][j]);

      printf("n");


      return 0;



      Produces the following output:



      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


      Live version at onlinegdb.






      share|improve this answer
























        up vote
        0
        down vote













        My solution. Using an "object" struct strangeite_s (from strange ite-rator). It allows ease reusing on different arrays and probably could be even rescaled to support n-dimensional arrays.

        The strangeite is initialized using _init function with specified dimensions sizes of an 2d array. Each time _loop is evaluated, the x and y positions are updated and the condition for loop end is checked (and returned). The _inc function should be called on each increment of the iterator.



        #include <stdio.h>
        #include <limits.h>
        #include <stddef.h>
        #include <assert.h>
        #include <stdint.h>
        #include <string.h>
        #include <stdbool.h>

        struct strangeite_s
        size_t steplen[2];
        size_t idx[2];
        size_t cursteplen;
        int direction;
        ;

        void strangeite_init(struct strangeite_s *t, size_t max_x, size_t max_y)

        assert(t != NULL);
        t->steplen[0] = max_y;
        t->steplen[1] = max_x;
        memset(t->idx, 0, sizeof(t->idx));
        t->direction = 0;
        t->cursteplen = t->steplen[0];


        bool strangeite_loop(const struct strangeite_s *t, size_t *x, size_t *y)

        if (x) *x = t->idx[0];
        if (y) *y = t->idx[1];
        for (size_t i = 0; i < sizeof(t->steplen)/sizeof(t->steplen[0]); ++i)
        if (t->steplen[i] == 0)
        return false;


        return true;


        void strangeite_inc(struct strangeite_s *t)

        if (t->cursteplen != 1)
        --t->cursteplen;
        else
        t->direction = ++t->direction % (2 * 2);
        t->cursteplen = --t->steplen[t->direction % 2];

        const size_t idx_to_change = t->direction % 2;
        t->idx[idx_to_change] = t->idx[idx_to_change] + ( t->direction < 2 ? +1 : -1 );


        int main()

        int var[5][5];

        struct strangeite_s i;
        strangeite_init(&i, 5, 5);
        int idx = 0;
        for (size_t x, y; strangeite_loop(&i, &x, &y); strangeite_inc(&i))
        var[y][x] = ++idx;


        for (size_t i = 0; i < 5; ++i)
        for (size_t j = 0; j < 5; ++j)
        printf("%d ", var[i][j]);

        printf("n");


        return 0;



        Produces the following output:



        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


        Live version at onlinegdb.






        share|improve this answer






















          up vote
          0
          down vote










          up vote
          0
          down vote









          My solution. Using an "object" struct strangeite_s (from strange ite-rator). It allows ease reusing on different arrays and probably could be even rescaled to support n-dimensional arrays.

          The strangeite is initialized using _init function with specified dimensions sizes of an 2d array. Each time _loop is evaluated, the x and y positions are updated and the condition for loop end is checked (and returned). The _inc function should be called on each increment of the iterator.



          #include <stdio.h>
          #include <limits.h>
          #include <stddef.h>
          #include <assert.h>
          #include <stdint.h>
          #include <string.h>
          #include <stdbool.h>

          struct strangeite_s
          size_t steplen[2];
          size_t idx[2];
          size_t cursteplen;
          int direction;
          ;

          void strangeite_init(struct strangeite_s *t, size_t max_x, size_t max_y)

          assert(t != NULL);
          t->steplen[0] = max_y;
          t->steplen[1] = max_x;
          memset(t->idx, 0, sizeof(t->idx));
          t->direction = 0;
          t->cursteplen = t->steplen[0];


          bool strangeite_loop(const struct strangeite_s *t, size_t *x, size_t *y)

          if (x) *x = t->idx[0];
          if (y) *y = t->idx[1];
          for (size_t i = 0; i < sizeof(t->steplen)/sizeof(t->steplen[0]); ++i)
          if (t->steplen[i] == 0)
          return false;


          return true;


          void strangeite_inc(struct strangeite_s *t)

          if (t->cursteplen != 1)
          --t->cursteplen;
          else
          t->direction = ++t->direction % (2 * 2);
          t->cursteplen = --t->steplen[t->direction % 2];

          const size_t idx_to_change = t->direction % 2;
          t->idx[idx_to_change] = t->idx[idx_to_change] + ( t->direction < 2 ? +1 : -1 );


          int main()

          int var[5][5];

          struct strangeite_s i;
          strangeite_init(&i, 5, 5);
          int idx = 0;
          for (size_t x, y; strangeite_loop(&i, &x, &y); strangeite_inc(&i))
          var[y][x] = ++idx;


          for (size_t i = 0; i < 5; ++i)
          for (size_t j = 0; j < 5; ++j)
          printf("%d ", var[i][j]);

          printf("n");


          return 0;



          Produces the following output:



          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


          Live version at onlinegdb.






          share|improve this answer












          My solution. Using an "object" struct strangeite_s (from strange ite-rator). It allows ease reusing on different arrays and probably could be even rescaled to support n-dimensional arrays.

          The strangeite is initialized using _init function with specified dimensions sizes of an 2d array. Each time _loop is evaluated, the x and y positions are updated and the condition for loop end is checked (and returned). The _inc function should be called on each increment of the iterator.



          #include <stdio.h>
          #include <limits.h>
          #include <stddef.h>
          #include <assert.h>
          #include <stdint.h>
          #include <string.h>
          #include <stdbool.h>

          struct strangeite_s
          size_t steplen[2];
          size_t idx[2];
          size_t cursteplen;
          int direction;
          ;

          void strangeite_init(struct strangeite_s *t, size_t max_x, size_t max_y)

          assert(t != NULL);
          t->steplen[0] = max_y;
          t->steplen[1] = max_x;
          memset(t->idx, 0, sizeof(t->idx));
          t->direction = 0;
          t->cursteplen = t->steplen[0];


          bool strangeite_loop(const struct strangeite_s *t, size_t *x, size_t *y)

          if (x) *x = t->idx[0];
          if (y) *y = t->idx[1];
          for (size_t i = 0; i < sizeof(t->steplen)/sizeof(t->steplen[0]); ++i)
          if (t->steplen[i] == 0)
          return false;


          return true;


          void strangeite_inc(struct strangeite_s *t)

          if (t->cursteplen != 1)
          --t->cursteplen;
          else
          t->direction = ++t->direction % (2 * 2);
          t->cursteplen = --t->steplen[t->direction % 2];

          const size_t idx_to_change = t->direction % 2;
          t->idx[idx_to_change] = t->idx[idx_to_change] + ( t->direction < 2 ? +1 : -1 );


          int main()

          int var[5][5];

          struct strangeite_s i;
          strangeite_init(&i, 5, 5);
          int idx = 0;
          for (size_t x, y; strangeite_loop(&i, &x, &y); strangeite_inc(&i))
          var[y][x] = ++idx;


          for (size_t i = 0; i < 5; ++i)
          for (size_t j = 0; j < 5; ++j)
          printf("%d ", var[i][j]);

          printf("n");


          return 0;



          Produces the following output:



          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


          Live version at onlinegdb.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 12 at 1:45









          Kamil Cuk

          8,1761422




          8,1761422




















              up vote
              0
              down vote













              It's possible to deterministically compute any one entry in the array A_i,j as a function only given the array size N, and i, j, in O(1), on-line, without any state, noticing the radius is a geometric progression. The space requirement is O(1) since one doesn't actually need the array to store the values; we can scan the array sequentially. However, like ray-tracing, it probably is slower, (up to a constant, it's still O(N^2).)



              #include <stdio.h>

              /* N: The size of the (simulated) array. */
              #define N (16)

              /* i, j: The array indices, as if, a[i][j]. */
              static int a(const int i, const int j)
              /* (x,y) translation of (i,-j) to the centre, scaled up 2x for int math. */
              const int x = 2 * i + 1 - N, y = -2 * j - 1 + N;
              /* Geometric series and an offset +fiddling to get the directionality. */
              return N*N - ((x < -y) ?
              (-x > -y) ? (x+1)*(x+1) - (y+x)/2 - 1: y*y + (x+y)/2 :
              (x > y) ? x*x + (x+y)/2 : (y+1)*y + (-x+y)/2);


              int main(void)
              int i, j;
              for(j = 0; j < N; j++)
              for(i = 0; i < N; i++)
              printf("%3d ", a(i, j));

              printf("n");

              return 0;






              share|improve this answer


























                up vote
                0
                down vote













                It's possible to deterministically compute any one entry in the array A_i,j as a function only given the array size N, and i, j, in O(1), on-line, without any state, noticing the radius is a geometric progression. The space requirement is O(1) since one doesn't actually need the array to store the values; we can scan the array sequentially. However, like ray-tracing, it probably is slower, (up to a constant, it's still O(N^2).)



                #include <stdio.h>

                /* N: The size of the (simulated) array. */
                #define N (16)

                /* i, j: The array indices, as if, a[i][j]. */
                static int a(const int i, const int j)
                /* (x,y) translation of (i,-j) to the centre, scaled up 2x for int math. */
                const int x = 2 * i + 1 - N, y = -2 * j - 1 + N;
                /* Geometric series and an offset +fiddling to get the directionality. */
                return N*N - ((x < -y) ?
                (-x > -y) ? (x+1)*(x+1) - (y+x)/2 - 1: y*y + (x+y)/2 :
                (x > y) ? x*x + (x+y)/2 : (y+1)*y + (-x+y)/2);


                int main(void)
                int i, j;
                for(j = 0; j < N; j++)
                for(i = 0; i < N; i++)
                printf("%3d ", a(i, j));

                printf("n");

                return 0;






                share|improve this answer
























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  It's possible to deterministically compute any one entry in the array A_i,j as a function only given the array size N, and i, j, in O(1), on-line, without any state, noticing the radius is a geometric progression. The space requirement is O(1) since one doesn't actually need the array to store the values; we can scan the array sequentially. However, like ray-tracing, it probably is slower, (up to a constant, it's still O(N^2).)



                  #include <stdio.h>

                  /* N: The size of the (simulated) array. */
                  #define N (16)

                  /* i, j: The array indices, as if, a[i][j]. */
                  static int a(const int i, const int j)
                  /* (x,y) translation of (i,-j) to the centre, scaled up 2x for int math. */
                  const int x = 2 * i + 1 - N, y = -2 * j - 1 + N;
                  /* Geometric series and an offset +fiddling to get the directionality. */
                  return N*N - ((x < -y) ?
                  (-x > -y) ? (x+1)*(x+1) - (y+x)/2 - 1: y*y + (x+y)/2 :
                  (x > y) ? x*x + (x+y)/2 : (y+1)*y + (-x+y)/2);


                  int main(void)
                  int i, j;
                  for(j = 0; j < N; j++)
                  for(i = 0; i < N; i++)
                  printf("%3d ", a(i, j));

                  printf("n");

                  return 0;






                  share|improve this answer














                  It's possible to deterministically compute any one entry in the array A_i,j as a function only given the array size N, and i, j, in O(1), on-line, without any state, noticing the radius is a geometric progression. The space requirement is O(1) since one doesn't actually need the array to store the values; we can scan the array sequentially. However, like ray-tracing, it probably is slower, (up to a constant, it's still O(N^2).)



                  #include <stdio.h>

                  /* N: The size of the (simulated) array. */
                  #define N (16)

                  /* i, j: The array indices, as if, a[i][j]. */
                  static int a(const int i, const int j)
                  /* (x,y) translation of (i,-j) to the centre, scaled up 2x for int math. */
                  const int x = 2 * i + 1 - N, y = -2 * j - 1 + N;
                  /* Geometric series and an offset +fiddling to get the directionality. */
                  return N*N - ((x < -y) ?
                  (-x > -y) ? (x+1)*(x+1) - (y+x)/2 - 1: y*y + (x+y)/2 :
                  (x > y) ? x*x + (x+y)/2 : (y+1)*y + (-x+y)/2);


                  int main(void)
                  int i, j;
                  for(j = 0; j < N; j++)
                  for(i = 0; i < N; i++)
                  printf("%3d ", a(i, j));

                  printf("n");

                  return 0;







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 12 at 15:12

























                  answered Nov 12 at 14:55









                  Neil Edelman

                  41228




                  41228



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53251914%2fwhat-is-the-better-way-to-loop-this-problem%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Top Tejano songwriter Luis Silva dead of heart attack at 64

                      政党

                      天津地下鉄3号線