Last active
April 22, 2024 03:59
-
-
Save coderodde/cd4f7b8b4a6f45662348f4a9ee73a208 to your computer and use it in GitHub Desktop.
A class for generating snail matrices.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Matrix = list[list[int]] | |
""" | |
This class is responsible for generating snail matrices of dimensions n * n. | |
""" | |
class SnailMatrixGenerator: | |
""" | |
Constructs this generator. | |
""" | |
def __init__(self, n): | |
self.n = n | |
self.matrix = [[0] * n for _ in range(n)] | |
self.deltas = [(1, 0), (0, 1), (-1, 0), (0, -1)] | |
self.delta_index = 0 | |
self.current_coordinate_x = 0 | |
self.current_coordinate_y = 0 | |
""" | |
Sets the given value at the current cursor location. | |
""" | |
def set_value_at_cursor(self, value): | |
self.matrix[self.current_coordinate_y][self.current_coordinate_x] = value | |
""" | |
Moves the current cursor location to the next valid position. | |
""" | |
def move_cell_cursor_to_next_location(self): | |
save_cx = self.current_coordinate_x | |
save_cy = self.current_coordinate_y | |
while True: | |
x = save_cx + self.deltas[self.delta_index][0] | |
y = save_cy + self.deltas[self.delta_index][1] | |
if self.check_current_coordinate_is_valid(x, y): | |
self.current_coordinate_x = x | |
self.current_coordinate_y = y | |
return | |
self.get_next_direction() | |
""" | |
Makes sure that (x, y) is within the matrix and is not yet set. | |
""" | |
def check_current_coordinate_is_valid(self, x, y): | |
# Here, the only possible range for x is [-1, self.n]. | |
if x == -1 or x == self.n: | |
return False | |
# Here, the only possible range for y is [-1, self.n]. | |
if y == -1 or y == self.n: | |
return False | |
# Make sure that the current position is not yet set: | |
return self.matrix[y][x] == 0 | |
""" | |
Changes the current progression direction. | |
""" | |
def get_next_direction(self): | |
if self.delta_index == len(self.deltas) - 1: | |
# Go wrap around: | |
self.delta_index = 0 | |
else: | |
# Just proceed to the next one: | |
self.delta_index += 1 | |
""" | |
Generates the snail pattern matrix. | |
""" | |
def generate(self): | |
value = 1 | |
while True: | |
self.set_value_at_cursor(value) | |
if value == self.n * self.n: | |
# Here, the matrix is full. | |
return self.matrix | |
value += 1 | |
# Move to the next cursor location: | |
self.move_cell_cursor_to_next_location() | |
if __name__ == "__main__": | |
def print_matrix(m: Matrix) -> None: | |
padding = len(str(len(m) ** 2)) | |
for row in m: | |
print(" ".join(f"{num:>{padding}}" for num in row)) | |
smg = SnailMatrixGenerator(4) | |
m = smg.generate() | |
print_matrix(m) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment