Last active
August 1, 2023 12:20
-
-
Save skatenerd/098d95fab32280f175580bfd3a5c48aa to your computer and use it in GitHub Desktop.
Clockwise matrix rotation
This file contains hidden or 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
def cycles(size, depth=0): | |
# we use (x,y) notation | |
if size < 2: | |
return iter([]) | |
not_aware_of_depth = (cycle(offset, size) for offset in range(0, size - 1)) | |
cycles_at_current_depth = ( | |
(go_right(go_down(p, depth), depth) for p in cycle) | |
for cycle in not_aware_of_depth | |
) | |
for x in cycles_at_current_depth: | |
yield x | |
for x in cycles(size - 2, depth + 1): | |
yield x | |
def go_right(point, distance): | |
x,y = point | |
return (x + distance, y) | |
def go_down(point, distance): | |
x,y = point | |
return (x, y + distance) | |
def go_left(point, distance): | |
x,y = point | |
return (x - distance, y) | |
def go_up(point, distance): | |
x,y = point | |
return (x, y - distance) | |
def cycle(offset, size): | |
# we use (x,y) notation | |
upper_left = (0,0) | |
upper_right = (size - 1, 0) | |
lower_right = (size - 1, size - 1) | |
lower_left = (0, size - 1) | |
return [ | |
go_right(upper_left, offset), | |
go_down(upper_right, offset), | |
go_left(lower_right, offset), | |
go_up(lower_left, offset) | |
] | |
def perform_cycle(matrix, cycle): | |
# rotate.perform_cycle([[0,1,2,3,4]], [(0,0), (1,0), (2,0), (3,0), (4,0)]) | |
# ----> [[4, 0, 1, 2, 3]] | |
first, *rest = cycle | |
x,y = first | |
return iterate_cycle(matrix, rest + [first], matrix[y][x]) | |
def iterate_cycle(matrix, cycle, swap): | |
# a 'cycle' of (a,b,c) means, | |
# 'put a where b was, then put b where c was, then put c where a was' | |
# so at any moment you have just put an item down, but you've displaced a new item | |
# and this code says, "put one thing down, and pick up a new one" | |
first, *rest = cycle | |
x,y = first | |
new_swap = matrix[y][x] | |
matrix[y][x] = swap | |
if len(rest) == 0: | |
return matrix | |
else: | |
return iterate_cycle(matrix, rest, new_swap) | |
def rotate_clockwise(m): | |
for c in cycles(len(m)): | |
perform_cycle(m,c) | |
return m | |
def make_square_matrix(size): | |
return [list(range(size* x, (size*x)+size)) for x in range(size)] | |
def main(): | |
m = make_square_matrix(1000) | |
print('starting') | |
rotate_clockwise(m) | |
print('done') | |
#abc | |
#def | |
#ghi | |
#gda | |
#heb | |
#ifc | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment