Skip to content

Instantly share code, notes, and snippets.

@skatenerd
Last active August 1, 2023 12:20
Show Gist options
  • Save skatenerd/098d95fab32280f175580bfd3a5c48aa to your computer and use it in GitHub Desktop.
Save skatenerd/098d95fab32280f175580bfd3a5c48aa to your computer and use it in GitHub Desktop.
Clockwise matrix rotation
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