Day 3
This commit is contained in:
parent
f88e8a6580
commit
ae59d75eeb
1 changed files with 94 additions and 0 deletions
94
day3.py
Normal file
94
day3.py
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
puzzle_input = 0 # TODO
|
||||||
|
|
||||||
|
def cardinals(distance):
|
||||||
|
d = 0
|
||||||
|
distance[1] = d
|
||||||
|
yield 1
|
||||||
|
|
||||||
|
d += 1
|
||||||
|
distance[2] = d
|
||||||
|
yield 2
|
||||||
|
|
||||||
|
while True:
|
||||||
|
v = (2*d)**2 - (d-1)
|
||||||
|
distance[v] = d
|
||||||
|
yield v
|
||||||
|
|
||||||
|
v = (2*d)**2 + (d+1)
|
||||||
|
distance[v] = d
|
||||||
|
yield v
|
||||||
|
|
||||||
|
v = (2*d + 1)**2 - d
|
||||||
|
distance[v] = d
|
||||||
|
yield v
|
||||||
|
|
||||||
|
v = (2*d + 1)**2 + (d+1)
|
||||||
|
distance[v] = d + 1
|
||||||
|
yield v
|
||||||
|
|
||||||
|
d += 1
|
||||||
|
|
||||||
|
def closest_cardinals(n, distance):
|
||||||
|
cs = cardinals(distance)
|
||||||
|
lo = next(cs)
|
||||||
|
hi = next(cs)
|
||||||
|
while not lo <= n <= hi:
|
||||||
|
lo, hi = hi, next(cs)
|
||||||
|
return lo, hi
|
||||||
|
|
||||||
|
def manhattan_to_center(n):
|
||||||
|
distance = {}
|
||||||
|
best = sorted(closest_cardinals(n, distance), key=lambda x: abs(n - x))[0]
|
||||||
|
return distance[best] + abs(n - best)
|
||||||
|
|
||||||
|
for inp, expected in [
|
||||||
|
(1, 0),
|
||||||
|
(2, 1),
|
||||||
|
(12, 3),
|
||||||
|
(23, 2),
|
||||||
|
(1024, 31),
|
||||||
|
]:
|
||||||
|
actual = manhattan_to_center(inp)
|
||||||
|
assert actual == expected, f'Expected {expected} got {actual}'
|
||||||
|
|
||||||
|
print(manhattan_to_center(puzzle_input))
|
||||||
|
|
||||||
|
def walking_order():
|
||||||
|
start = (0, 0)
|
||||||
|
R, D, L, U = [(+1, 0), (0, -1), (-1, 0), (0, +1)]
|
||||||
|
|
||||||
|
yield R
|
||||||
|
yield U
|
||||||
|
|
||||||
|
count = 2
|
||||||
|
while True:
|
||||||
|
for deltas in [(L, D), (R, U)]:
|
||||||
|
for delta in deltas:
|
||||||
|
for _ in range(count):
|
||||||
|
yield delta
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
def neighbors(cell):
|
||||||
|
x, y = cell
|
||||||
|
for dx in range(-1, 2):
|
||||||
|
for dy in range(-1, 2):
|
||||||
|
if dx == dy == 0: continue
|
||||||
|
yield (x+dx, y+dy)
|
||||||
|
|
||||||
|
def sum_neighbors_until(limit):
|
||||||
|
grid = {}
|
||||||
|
deltas = walking_order()
|
||||||
|
|
||||||
|
cell = (0, 0)
|
||||||
|
grid[cell] = 1
|
||||||
|
|
||||||
|
while True:
|
||||||
|
x, y = cell
|
||||||
|
dx, dy = next(deltas)
|
||||||
|
cell = (x+dx, y+dy)
|
||||||
|
value = sum(grid.get(n, 0) for n in neighbors(cell))
|
||||||
|
grid[cell] = value
|
||||||
|
if value > limit:
|
||||||
|
return value
|
||||||
|
|
||||||
|
print(sum_neighbors_until(puzzle_input))
|
||||||
Loading…
Reference in a new issue