Looping in a Spiral Outside-In

Looping in a spiral outside-in

Without loss of generality, let's write the array as:

arr = [
[ 1, 2, 3, 4,],
[12, 13, 14, 5,],
[11, 16, 15, 6,],
[10, 9, 8, 7,]
]

The desired result is:

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

I will use a helper:

def rotate_anticlockwise(arr)
arr.map(&:reverse).transpose
end

For example:

rotate_anticlockwise(arr)
#=> [[4, 5, 6, 7],
# [3, 14, 15, 8],
# [2, 13, 16, 9],
# [1, 12, 11, 10]]

We can now compute the desired result as follows:

out = []
a = arr.map(&:dup)
while a.any?
out.concat(a.shift)
a = rotate_anticlockwise(a)
end
out
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

Looping in a spiral

Here's my solution (in Python):

def spiral(X, Y):
x = y = 0
dx = 0
dy = -1
for i in range(max(X, Y)**2):
if (-X/2 < x <= X/2) and (-Y/2 < y <= Y/2):
print (x, y)
# DO STUFF...
if x == y or (x < 0 and x == -y) or (x > 0 and x == 1-y):
dx, dy = -dy, dx
x, y = x+dx, y+dy

how to write a code that prints an specific numerical spiral pattern in c using for loops without array

One solution is to take code that already can fill an array with the spiral pattern, and put it in a nested loop that uses that code to find the number for the current printing position. There are certainly more efficient solutions, but this allows you to transform a solution that works for arrays into one that does not need arrays.

The first program here uses an array to print a spiral pattern of numbers. The second program is a modified version of the first that prints a number when the printing position matches the position in the spiral loop instead of storing it in an array. I'll leave it to you to see if you can modify your existing code to accomplish this.

Using a 2d array:

/* A program that prints a spiral using a 2d array */

#include <stdio.h>

int main(int argc, char *argv[])
{
int size;
if (argc < 2 || (sscanf(argv[1], "%d", &size) != 1) || size < 1) {
fprintf(stderr, "Usage: spiral N [N > 0]\n");
return 1;
}

int arr[size][size];
int num_elems = size * size;


enum Dir { RIGHT, DOWN, LEFT, UP };
int num_directions = 4;

int side_len = size;
int row = 0; // arr row index
int col = 0; // arr column index
int pos = 0; // position in a side

// travel around the spiral to fill the array
enum Dir direction = RIGHT;
for (int i = 0; i < num_elems; i++) {
arr[row][col] = i + 1;
++pos;

if (pos == side_len) { // change direction
direction = (direction + 1) % num_directions;
pos = 0;

// having changed direction, shorten side_len in two cases
if (direction == DOWN || direction == UP) {
--side_len;
}
}

switch (direction) {
case RIGHT:
++col;
break;
case DOWN:
++row;
break;
case LEFT:
--col;
break;
case UP:
--row;
break;
default:
fprintf(stderr, "Unexpected value in switch statement\n");
return 1;
}
}

for (row = 0; row < size; row++) {
for (col = 0; col < size; col++) {
printf("%4d", arr[row][col]);
}
putchar('\n');
}
putchar('\n');

return 0;
}

Using only loops:

/* A program that prints a spiral using loops but no arrays */

#include <stdio.h>

int main(int argc, char *argv[])
{
int size;
if (argc < 2 || (sscanf(argv[1], "%d", &size) != 1) || size < 0) {
fprintf(stderr, "Usage: spiral N [N >= 0]\n");
return 1;
}

int num_elems = size * size;

enum Dir { RIGHT, DOWN, LEFT, UP };
int num_directions = 4;

// loop printing positions: print a row at a time
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
int side_len = size; // length of current side
int row = 0; // arr row index
int col = 0; // arr column index
int pos = 0; // position in a side

// travel around spiral until printing number is reached
enum Dir direction = RIGHT;
for (int i = 0; i < num_elems; i++) {
if (row == y && col == x) { // print and escape loop
printf("%4d", i + 1);
break;
}
++pos;

if (pos == side_len) { // change direction
direction = (direction + 1) % num_directions;
pos = 0;

// having changed direction, shorten side_len in two cases
if (direction == DOWN || direction == UP) {
--side_len;
}
}

switch (direction) {
case RIGHT:
++col;
break;
case DOWN:
++row;
break;
case LEFT:
--col;
break;
case UP:
--row;
break;
default:
fprintf(stderr, "Unexpected value in switch statement\n");
return 1;
}
}
}
// newline after row
putchar('\n');
}
// newline after printing all numbers
putchar('\n');

return 0;
}

Here are a couple of sample interactions with the second program:

>$ ./spiral2 3
1 2 3
8 9 4
7 6 5

>$ ./spiral2 6
1 2 3 4 5 6
20 21 22 23 24 7
19 32 33 34 25 8
18 31 36 35 26 9
17 30 29 28 27 10
16 15 14 13 12 11

Print 2-D Array in clockwise expanding spiral from center

Let's identify the patterns first ..

Even-Size Square Matrix, Example: 4x4

  07 > 08 > 09 > 10
^ v
06 (01)> 02 11
^ v v
05 < 04 < 03 12
v
[16]< 15 < 14 < 13

Starting Point: [2, 2] ~ [SIZE/2, SIZE/2]

Ending Point: [4, 1] ~ [SIZE, 1]

Chains: Count(K-chain)=2 for K = 1..(SIZE-2)
+ 3 for Count = SIZE-1

Odd-Size Square Matrix, Example: 5x5

  21 > 22 > 23 > 24 >[25]
^
20 07 > 08 > 09 > 10
^ ^ v
19 06 (01)> 02 11
^ ^ v v
18 05 < 04 < 03 12
^ v
17 < 16 < 15 < 14 < 13

Starting Point: [2, 2] ~ [⌊SIZE/2⌋, ⌊SIZE/2⌋]

Ending Point: [1, 5] ~ [1, SIZE]

Chains: Count(K-chain)=2 for K = 1..(SIZE-2)
+ 3 for Count = SIZE-1

Live Code

void print_spiral (int ** matrix, int size)
{
int x = 0; // current position; x
int y = 0; // current position; y
int d = 0; // current direction; 0=RIGHT, 1=DOWN, 2=LEFT, 3=UP
int c = 0; // counter
int s = 1; // chain size

// starting point
x = ((int)floor(size/2.0))-1;
y = ((int)floor(size/2.0))-1;

for (int k=1; k<=(size-1); k++)
{
for (int j=0; j<(k<(size-1)?2:3); j++)
{
for (int i=0; i<s; i++)
{
std::cout << matrix[x][y] << " ";
c++;

switch (d)
{
case 0: y = y + 1; break;
case 1: x = x + 1; break;
case 2: y = y - 1; break;
case 3: x = x - 1; break;
}
}
d = (d+1)%4;
}
s = s + 1;
}
}

how to build spiral square matrix using recursion?

#include <stdio.h>

void build_matrix(int msize, int a[msize][msize], int size, int value){
int i, row, col;
if(size < 1)
return;
row = col = (msize - size) / 2;
if(size==1){
a[row][col] = value;
return;
}
for(i=0;i<size-1;++i)
a[row][col++] = value++;//RIGHT
for(i=0;i<size-1;++i)
a[row++][col] = value++;//DOWN
for(i=0;i<size-1;++i)
a[row][col--] = value++;//LEFT
for(i=0;i<size-1;++i)
a[row--][col] = value++;//UP
build_matrix(msize, a, size-2, value);
}

int main(){
int size;
printf("input size : ");
scanf("%d", &size);
int a[size][size];
build_matrix(size, a, size, 1);
for(int r=0;r<size;++r){
for(int c=0;c<size;++c)
printf("%3d ", a[r][c]);
printf("\n");
}

return 0;
}


Related Topics



Leave a reply



Submit