Nested loops for creating a spiral shape pattern in c

两盒软妹~` 提交于 2019-12-01 10:39:31

After being thoroughly nerd-sniped, I came up with this:

#include <stdio.h>

void print_spiral(int size)
{
    for (int y = 0; y < size; ++y)
    {
        for (int x = 0; x < size; ++x)
        {
            // reflect (x, y) to the top left quadrant as (a, b)
            int a = x;
            int b = y;
            if (a >= size / 2) a = size - a - 1;
            if (b >= size / 2) b = size - b - 1;

            // calculate distance from center ring
            int u = abs(a - size / 2);
            int v = abs(b - size / 2);
            int d = u > v ? u : v;
            int L = size / 2;
            if (size % 4 == 0) L--;

            // fix the top-left-to-bottom-right diagonal
            if (y == x + 1 && y <= L) d++;

            printf((d + size / 2) % 2 == 0 ? "X" : " ");
        }

        printf("\n");
    }
}

As others mentioned, it might be more intuitive to allocate an array representing the grid, and draw the spiral into the array (within which you can move freely), then print the array. But, this solution uses O(1) memory.

It could almost certainly be optimized and simplified a bit, but I'll "leave that as an exercise for the reader" as I've already spent too much time on this ;-)


Update

I'm not going to spend any more time on this, but I had an idea for a second attempt that might result in simpler code. If you check the output at increasingly large sizes, a pattern emerges:

Within each quadrant, the pattern is regular and can be easily coded. I think you would just have to carefully classify the (x, y) coordinates into one of the four quadrants and then apply the appropriate pattern.

The most sensible approach is to create a 2d array, then fill it with the * that you want.

Alternatively, you can try to come up with some "just in time" logic to avoid a buffer. This is more complicated.

I came up with an approach by thinking of the spiral as four different triangles that form a square. Here I have printed "a,b,c,d" for each of the four triangles to show what I mean:

aaaaaaaaaac
          c
 baaaaaac c
 b      c c
 b baac c c
 b b dd c c
 b b    c c
 b dddddd c
 b        c
 dddddddddd  

There are two tricky parts to this. One is to align the diagonals correctly. Not so hard with with trial and error. The other tricky party is that not all squares divide into alternating lines the same way. You can see in the example above a square n=11, the left side is shifted by one. Perhaps there is a better solution, but this attempts to create alternating rows and columns.

n = 11;
for (int i = 0; i < n; i++)
{
    for (int j = 0; j < n; j++)
    {
        // top
        if (j > i - 2 && j < n - i && i % 2 == (n&1)) printf("a");
        // left
        else if (j < i - 1 && j < n - i && j % 2 == (n & 1)) printf("b");
        // right
        else if (j > n - i -1&& j > i && j % 2 == ((n+1) & 1)) printf("c");
        // bottom
        else if (j < i + 1 && j > n - i - 1 && i % 2 == ((n + 1) & 1)) printf("d");
        else printf(" ");
    }
    printf("\n");
}

I would recommend taking a look at the NCurses library. It contains many methods for moving the cursor in the terminal window, such as mvaddch() and curs_set().

Here is a document that contains everything you'd need to know on how to use NCurses.

However, if you don't want to use external libraries, then you could define a 2D array of ints or bools and then print a * where an index is 1 or true, respectively.

Example of the latter:

#include <stdbool.h>  //You need to include this header file if you want to use 'bool's
...
//Using a 10x10 array for this example
bool stars[10][10] = { /* initialize the 2D array here */ };
...
//Get the length of a row
int rowLength = (sizeof stars[0]) / (sizeof stars[0][0]);

//Get the amount of rows
int rowAmount = (sizeof stars) / (sizeof stars[0]));

//Print the spiral using the array "stars"
for(int r = 0; r < rowAmount; r++){
    for(int c = 0; c < rowLength; c++){
        if(stars[r][c])
            printf("*");
        else
            printf(" ");
    }
    printf("\n");
}
...
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!