Search code examples
cfor-loopwhile-loopspiral

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


I want to write a code that gets the integer n from the user and prints numbers in a spiral pattern from 1 to n*n without using arrays. output for entering 5

input3
output:
1 2 3
8 9 4
7 6 5

do you have any suggestions on how to write this code?

EDIT: here is the code using arrays:

#include <stdio.h>

int main(){
/*declaration of the variables*/
int i, j, ascendingNumbers;
int leftAndTop, rightAndBottom;
int size;
scanf("%d", &size);
int matrix[size][size];

leftAndTop = 0;
rightAndBottom = size - 1;
ascendingNumbers = 1;

/*filling the array*/
for(i = 1; i <= size/2; i++, leftAndTop++, rightAndBottom--){
    /*left to right*/
    for(j = leftAndTop; j <= rightAndBottom; j++, ascendingNumbers++){
        matrix[leftAndTop][j] = ascendingNumbers;
    }

    /*top to bottom*/
    for(j = leftAndTop + 1; j <= rightAndBottom; j++, ascendingNumbers++){
        matrix[j][rightAndBottom] = ascendingNumbers;
    }

    /*right to left*/
    for(j = rightAndBottom-1; j >= leftAndTop; j--, ascendingNumbers++){
        matrix[rightAndBottom][j] = ascendingNumbers;
    }

    /*bottom to top*/
    for(j = rightAndBottom - 1; j >= leftAndTop+1; j--, ascendingNumbers++){
        matrix[j][leftAndTop] = ascendingNumbers;
    }
}

/*fill the center for odd size*/
if(size % 2){
    matrix[leftAndTop][j + 1] = ascendingNumbers;
}

/*print*/
for(i = 0; i < size; i++){
    for(j = 0; j < size; j++){
        printf("%d  ", matrix[i][j]);
    }
    printf("\n");
}

return 0;
}

Solution

  • 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