what is the better way to loop this problem?
up vote
1
down vote
favorite
#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 loop
c arrays matrix multidimensional-array
|
show 4 more comments
up vote
1
down vote
favorite
#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 loop
c arrays matrix multidimensional-array
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 anyfor
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 singlewhile
loop and nofor
s, keep in mind that thatwhile
would do many more iterations than any singlefor
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 usingfor
loops.
– Dmitri
Nov 11 at 19:09
|
show 4 more comments
up vote
1
down vote
favorite
up vote
1
down vote
favorite
#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 loop
c arrays matrix multidimensional-array
#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 loop
c arrays matrix multidimensional-array
c arrays matrix multidimensional-array
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 anyfor
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 singlewhile
loop and nofor
s, keep in mind that thatwhile
would do many more iterations than any singlefor
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 usingfor
loops.
– Dmitri
Nov 11 at 19:09
|
show 4 more comments
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 anyfor
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 singlewhile
loop and nofor
s, keep in mind that thatwhile
would do many more iterations than any singlefor
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 usingfor
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 for
s, 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 for
s, 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
|
show 4 more comments
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
it works perfectly ! but can you explain a bit whatvi
vj
ii
jj
means ?
– Степан Бандера
Nov 11 at 19:30
1
vi
andvj
tell where you are currently going (think of it as a velocity vector); they are the increments fori
andj
.ii
andjj
are just temporaries.
– Nelfeal
Nov 11 at 19:32
1
This is one ugly code...
– kfx
Nov 11 at 19:35
1
@СтепанБандераi
andj
are positions.vi
andvj
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
|
show 5 more comments
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
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
|
show 7 more comments
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.
add a comment |
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;
add a comment |
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
it works perfectly ! but can you explain a bit whatvi
vj
ii
jj
means ?
– Степан Бандера
Nov 11 at 19:30
1
vi
andvj
tell where you are currently going (think of it as a velocity vector); they are the increments fori
andj
.ii
andjj
are just temporaries.
– Nelfeal
Nov 11 at 19:32
1
This is one ugly code...
– kfx
Nov 11 at 19:35
1
@СтепанБандераi
andj
are positions.vi
andvj
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
|
show 5 more comments
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
it works perfectly ! but can you explain a bit whatvi
vj
ii
jj
means ?
– Степан Бандера
Nov 11 at 19:30
1
vi
andvj
tell where you are currently going (think of it as a velocity vector); they are the increments fori
andj
.ii
andjj
are just temporaries.
– Nelfeal
Nov 11 at 19:32
1
This is one ugly code...
– kfx
Nov 11 at 19:35
1
@СтепанБандераi
andj
are positions.vi
andvj
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
|
show 5 more comments
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
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
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 whatvi
vj
ii
jj
means ?
– Степан Бандера
Nov 11 at 19:30
1
vi
andvj
tell where you are currently going (think of it as a velocity vector); they are the increments fori
andj
.ii
andjj
are just temporaries.
– Nelfeal
Nov 11 at 19:32
1
This is one ugly code...
– kfx
Nov 11 at 19:35
1
@СтепанБандераi
andj
are positions.vi
andvj
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
|
show 5 more comments
it works perfectly ! but can you explain a bit whatvi
vj
ii
jj
means ?
– Степан Бандера
Nov 11 at 19:30
1
vi
andvj
tell where you are currently going (think of it as a velocity vector); they are the increments fori
andj
.ii
andjj
are just temporaries.
– Nelfeal
Nov 11 at 19:32
1
This is one ugly code...
– kfx
Nov 11 at 19:35
1
@СтепанБандераi
andj
are positions.vi
andvj
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
|
show 5 more comments
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
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
|
show 7 more comments
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
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
|
show 7 more comments
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
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
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
|
show 7 more comments
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
|
show 7 more comments
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 12 at 1:45
Kamil Cuk
8,1761422
8,1761422
add a comment |
add a comment |
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;
add a comment |
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;
add a comment |
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;
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;
edited Nov 12 at 15:12
answered Nov 12 at 14:55
Neil Edelman
41228
41228
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 nofor
s, keep in mind that thatwhile
would do many more iterations than any singlefor
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 usingfor
loops.– Dmitri
Nov 11 at 19:09