94 lines
1.9 KiB
Python
94 lines
1.9 KiB
Python
class Walker:
|
|
def __init__(self):
|
|
self.x = 0
|
|
self.y = 0
|
|
self.address = 1
|
|
self.current_radius = 0
|
|
self.cells = {(0, 0): 1}
|
|
|
|
def right(self):
|
|
self.x += 1
|
|
self.address += 1
|
|
|
|
def left(self):
|
|
self.x -= 1
|
|
self.address += 1
|
|
|
|
def up(self):
|
|
self.y += 1
|
|
self.address += 1
|
|
|
|
def down(self):
|
|
self.y -= 1
|
|
self.address += 1
|
|
|
|
def walk(self):
|
|
# check if time to switch bands
|
|
if self.x == self.current_radius and self.y == -1 * self.current_radius:
|
|
self.right()
|
|
self.current_radius += 1
|
|
self.populate_cell()
|
|
return
|
|
|
|
# figure out side and move accordingly
|
|
if abs(self.y) < self.current_radius: # left or right
|
|
if self.x > 0: # right
|
|
self.up()
|
|
else: # left
|
|
self.down()
|
|
elif abs(self.x) < self.current_radius: # top or bottom
|
|
if self.y > 0: # top
|
|
self.left()
|
|
else: # bottom
|
|
self.right()
|
|
else: # corner
|
|
if self.x > 0 and self.y > 0: # top right
|
|
self.left()
|
|
elif self.x < 0 and self.y > 0: # top left
|
|
self.down()
|
|
elif self.x < 0 and self.y < 0: # bottom left
|
|
self.right()
|
|
elif self.x > 0 and self.y < 0: # bottom right
|
|
self.up()
|
|
self.populate_cell()
|
|
|
|
def populate_cell(self):
|
|
total = 0
|
|
for dx in 1, 0, -1:
|
|
for dy in 1, 0, -1:
|
|
if dx != 0 or dy != 0:
|
|
coords = (self.x + dx, self.y + dy)
|
|
total += self.cells.get(coords, 0)
|
|
self.cells[self.x, self.y] = total
|
|
|
|
def test(self, steps=1):
|
|
for i in range(steps):
|
|
self.walk()
|
|
self.display()
|
|
|
|
def display(self):
|
|
print('Address:', self.address)
|
|
print('Value:', self.cells[self.x, self.y])
|
|
print(f'Position: ({self.x}, {self.y})')
|
|
print('Radius:', self.current_radius)
|
|
|
|
if __name__ == '__main__':
|
|
n = 325489
|
|
walker = Walker()
|
|
'''
|
|
# part 1
|
|
while walker.address < n:
|
|
walker.walk()
|
|
|
|
walker.display()
|
|
|
|
print('Distance:', abs(walker.x) + abs(walker.y))
|
|
'''
|
|
|
|
# part 2
|
|
while walker.cells[walker.x, walker.y] <= n:
|
|
walker.walk()
|
|
|
|
walker.display()
|
|
|