Blog

Navigating 2D grids with complex numbers.

Grid navigation involves manipulating row and column indices. However, we can take a creative leap by representing grid positions as complex numbers, where the real part corresponds to the row and the imaginary part to the column. This approach simplifies grid traversal and allows for concise and intriguing operations, leveraging the mathematical properties of complex numbers.

GRID = [
    ["NW", "N", "NE"],
    ["W",  "C",  "E"],
    ["SW", "S", "SE"],
]

# Given a grid, dynamically define the starting point, the center.
# In our case, this would be the "C", at [1, 1].
row_center = len(GRID) // 2     # 1.
col_center = len(GRID[0]) // 2  # 1.


# We define the starting point as a complex number (1+1j), which is a number
# with a real and imaginary part. The Real part represents the row and the
# Imaginary part represents the column.
starting_point = complex(row_center, col_center)
print(starting_point)  # (1+1j)
#                         │└┬┘
#                         │ │
#                         │ └── Imaginary part, denoted by the "j" suffix.
#                         └── Real part.


# We can move around the grid by adding or subtracting either a real and/or
# imaginary part. Note, if either part is 0, we can omit it. We can re-imagine
# the grid with "C" as the starting point as following:

# (-1-1j) │ (-1+0j) │ (-1+1j)
# ────────────────────────────
# (0-1j)  │   "C"   │ (0+1j)
# ────────────────────────────
# (+1-1j) │ (+1+0j) │ (+1+1j)

# From "C" to move down towards "S", we add 1:
starting_point + 1

# From "C" to move right towards "E", we subtract 1j:
starting_point - 1j

# From "C" to move diagonally towards "NW", we subtract -1-1j:
starting_point - 1 - 1j

# These operations result in another complex number, which we can then break
# down into a row and column to get the value of the grid. E.g.
position = starting_point + 1         # -> "S".
position += 1j                        # -> "SE".
position += -2                        # -> "NE".
position += 1 - 2j                    # -> "W".

# These operations can be chained together. E.g.
starting_point + 1 + 1j - 2 + 1 - 2j  # -> "W".

# To break down the complex number into the row and column, we can simply
# extract the parts:
row = int(position.real)
col = int(position.imag)
print(GRID[row][col])  # "W".