DEV Community

dev.to staff
dev.to staff

Posted on

2 1

Daily Challenge #98 - Make a Spiral

Your task is to create an NxN spiral with a given size.
For example, a spiral with size 5 should look like this:

00000
....0
000.0
0...0
00000

and with the size 10:

0000000000
.........0
00000000.0
0......0.0
0.0000.0.0
0.0..0.0.0
0.0....0.0
0.000000.0
0........0
0000000000

Return value should contain array of arrays, of 0 and 1, for example for given size 5 result should be:

[[1,1,1,1,1],[0,0,0,0,1],[1,1,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]

Because of the edge-cases for tiny spirals, the size will be at least 5.

General rule-of-a-thumb is, that the snake made with '1' cannot touch to itself.


This challenge comes from Bugari on CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

Top comments (6)

Collapse
 
erezwanderman profile image
erezwanderman • Edited

Javascript:

const spiral = n => {
  return Array(n)
    .fill(Array(n).fill())
    .map((x, r) =>
      x.map((y, c) => {
        return +(
          // top
          (r < n / 2 && r % 2 === 0 && c >= r - 2 && c <= n - r - 1) ||
          // right
          ((n - c) % 2 === 1 && r > n - c - 1 && r <= c) ||
          // bottom
          ((n - r) % 2 === 1 && c > n - r - 1 && c < r) ||
          // left
          (c % 2 === 0 && r > c + 1 && r < n - c)
        );
      })
    );
};

See it in action: codesandbox.io/s/hopeful-nash-wvvc...

Collapse
 
erezwanderman profile image
erezwanderman

Now I'm working on generalizing it to non square matrix

Collapse
 
erezwanderman profile image
erezwanderman
const spiral = (rowNum, colNum) => {
  return Array(rowNum)
    .fill(Array(colNum).fill())
    .map((x, r) =>
      x.map((_, c) => {
        return +(
          // top
          (r < rowNum / 2 && r % 2 === 0 && r - 2 <= c && c <= colNum - r - 1) ||
          // right
          (c > (colNum - 2) / 2 && (colNum - c) % 2 === 1 && colNum - c - 2 < r && r <= rowNum - (colNum - c)) ||
          // bottom
          (r > rowNum / 2 && (rowNum - r) % 2 === 1 && rowNum - r - 2 < c && c < colNum - (rowNum - r)) ||
          // left
          (c < (colNum - 2) / 2 && c % 2 === 0 && r > c + 1 && r < rowNum - c)
        );
      })
    );
};
Collapse
 
edreeseg profile image
Ed Reeseg • Edited

Definitely not as efficient as iterating through each index once and deciding on a 1 or a 0 arithmetically, but I wanted to try solving this one in a different way to see how it worked out. I'd probably go back and refactor this a bit, given the choice, but it seems to work well enough.

If we had a way of initializing the array values at 0, this method could actually be more efficient, as it wouldn't necessitate visiting every single index, just those touched by the spiral.

C

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char **argv)
{
    int size = atoi(argv[1]);
    if (argc != 2 || size < 5)
    {
        printf("Usage: ./make-a-spiral.c int\n");
        return 1;
    }
    int result[size][size];
    int x = 0,
        y = 0,
        dir = 1,
        horizontal = 1,
        boundary_x = 0,
        boundary_y = 0,
        turns = 0;
    // Iterate through our result array and set the default to 0,
    // as otherwise we will end up with garbage values polluting the result.
    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < size; j++)
        {
            result[i][j] = 0;
        }
    }
    // Change our x and y location as is appropriate, and check when we 
    // need to turn.
    while (turns < size)
    {
        result[y][x] = 1;
        if (y == 0 + boundary_y && !horizontal && dir == -1)
        {
            horizontal = 1;
            dir *= -1;
            turns++;
        }
        else if (y == size - boundary_y - 1 && !horizontal && dir == 1)
        {
            horizontal = 1;
            boundary_y += 2;
            dir *= -1;
            turns++;
        }
        else if (x == size - boundary_x - 1 && horizontal && dir == 1)
        {
            horizontal = 0;
            turns++;
        }
        else if (y != 0 && x == 0 + boundary_x && horizontal && dir == -1)
        {
            horizontal = 0;
            boundary_x += 2;
            turns++;
        }
        // Handle movement
        if (horizontal)
        {
            x += dir;
        }
        else 
        {
            y += dir;
        }
    }
    // Iterate through once more to print the resulting spiral.
    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < size; j++)
        {
            printf("%c", result[i][j] ? '0' : '.');
        }
        printf("\n");
    }
    return 0;
}
Collapse
 
michaeltharrington profile image
Michael Tharrington

Collapse
 
aschwin profile image
Aschwin Wesselius

Sprial or spiral?

The title says sprial, the article says spiral.

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay