advent/2017/day03.py
2017-12-13 16:48:23 -08:00

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()