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
Extract Number from String in Ruby
Rails 4.0 Strong Parameters Nested Attributes With a Key That Points to a Hash
Why Isn't Self Always Needed in Ruby/Rails/Activerecord
Fibonacci Sequence in Ruby (Recursion)
What's the Precedence of Ruby'S Method Call
How to Avoid Trailing Empty Items Being Removed When Splitting Strings
Unable to Obtain Stable Firefox Connection in 60 Seconds (127.0.0.1:7055)
Undefined Method Attr_Accessible
Why Isn't Current Directory on My Ruby Path
Why Do Two Strings Separated by Space Concatenate in Ruby
Ruby: Problem Installing Eventmachine Under Windows 7
Rspec: Expect VS Expect With Block - What's the Difference
How Do Rvm and Rbenv Actually Work
Rails - Best-Practice: How to Create Dependent Has_One Relations