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!

Warp.dev image

The best coding agent. Backed by benchmarks.

Warp outperforms every other coding agent on the market, and gives you full control over which model you use. Get started now for free, or upgrade and unlock 2.5x AI credits on Warp's paid plans.

Download Warp

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.

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Announcing the First DEV Education Track: "Build Apps with Google AI Studio"

The moment is here! We recently announced DEV Education Tracks, our new initiative to bring you structured learning paths directly from industry experts.

Dive in and Learn

DEV is bringing Education Tracks to the community. Dismiss if you're not interested. ❤️