I have a challenge for you to try. First, please look at this code.
function unspiral (i, j) {const n = Math.max(Math.abs(i), Math.abs(j))return 4 * n * n + (j > i ? -1 : 1) * (2 * n - i - j)}
By reading the code, did you understand what the code does?
How long did it take you to figure that out?
Here’s a 2D spiral pattern:
As you can see in the diagram above, the spiral is centered at (0, 0). It starts at the tile above the center, and then works its way clockwise.
The function unspiral(i, j)
takes the coordinates (i, j)
and returns the corresponding number. Let’s assume that i
and j
can be arbitrarily large.
For example:
unspiral(0, 0) === 0
unspiral(-2, -1) === 9
unspiral(-123, 456) === 831165
Here’s the solution I came up with:
function unspiral (i, j) {const n = Math.max(Math.abs(i), Math.abs(j))return 4 * n * n + (j > i ? -1 : 1) * (2 * n - i - j)}
But as you can see, the code looks very cryptic and mathematical. It might take several minutes to understand the code. And you need to think deeply in order to change or extend it to your needs.
A requirement change may require the spiral to:
I’ve written several pieces code that looked like this, and very few people could change it.
Although it’s a pure, small, testable, dependency-free function that does one thing, but it isn’t so pleasant to read and it’s hard to extend. So I thought, maybe, my code is not clean enough.
I hope to learn from other developers, that’s why I came up with this challenge.
Your challenge is to rewrite the unspiral
function, in a way that:
I would like to see your solutions. Thanks for reading.