Clean code challenge: Unspiral

August 19th 2017

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?

The spiral

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:

  • Be centered at a different coordinate.
  • Start running at a different number.
  • Rotate in an opposite direction (counter-clockwise).
  • Start at a different side.

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:

  • A programmer can easily understand what it does and how it works by reading the function’s code. Comments are allowed.
  • A programmer can easily modify, extend or re-use the function to suit their needs.
  • The algorithm runs in O(1).

I would like to see your solutions. Thanks for reading.

More by Thai Pangsakulyanont

More Related Stories