99 lines
2.0 KiB
Python
99 lines
2.0 KiB
Python
import sys
|
|
import lib
|
|
from collections import defaultdict
|
|
|
|
|
|
data = open(0).read().strip()
|
|
|
|
|
|
def more_efficient_part_1(data):
|
|
def corners():
|
|
layer = 0
|
|
corner = 1
|
|
edge_len = 3
|
|
yield (corner, layer, edge_len)
|
|
while True:
|
|
corner += (edge_len - 1) * 4
|
|
layer += 1
|
|
yield (corner, layer, edge_len)
|
|
edge_len += 2
|
|
|
|
square = int(data)
|
|
corner, layer, edge_len = 0, 0, 0
|
|
for corner, layer, edge_len in corners():
|
|
if square < corner:
|
|
break
|
|
|
|
coord = (layer, layer)
|
|
while corner != square:
|
|
for dir in [(0, -1), (-1, 0), (0, 1), (1, 0)]:
|
|
for _ in range(edge_len - 1):
|
|
corner -= 1
|
|
coord = lib.add2(coord, dir)
|
|
if corner == square:
|
|
break
|
|
if corner == square:
|
|
break
|
|
return sum(map(abs, coord))
|
|
|
|
|
|
|
|
def walk_spiral():
|
|
yield (0, 0), 1
|
|
yield (0, 1), 2
|
|
|
|
value = 2
|
|
coord = (0, 1)
|
|
step_len = 1
|
|
|
|
up = (-1, 0)
|
|
left = (0, -1)
|
|
down = (1, 0)
|
|
right = (0, 1)
|
|
|
|
|
|
while True:
|
|
for _ in range(step_len):
|
|
coord = lib.add2(coord, up)
|
|
value += 1
|
|
yield coord, value
|
|
|
|
step_len += 1
|
|
|
|
for _ in range(step_len):
|
|
coord = lib.add2(coord, left)
|
|
value += 1
|
|
yield coord, value
|
|
|
|
for _ in range(step_len):
|
|
coord = lib.add2(coord, down)
|
|
value += 1
|
|
yield coord, value
|
|
|
|
step_len += 1
|
|
for _ in range(step_len):
|
|
coord = lib.add2(coord, right)
|
|
value += 1
|
|
yield coord, value
|
|
|
|
values = defaultdict(int)
|
|
values[(0, 0)] = 1
|
|
part_1 = False
|
|
|
|
for coord, value in walk_spiral():
|
|
if part_1 and value == int(data):
|
|
print(sum(map(abs, coord)))
|
|
break
|
|
|
|
nval = 0
|
|
for d in lib.nbs8:
|
|
nb = lib.add2(coord, d)
|
|
nval += values[nb]
|
|
|
|
if nval > 0:
|
|
values[coord] = nval
|
|
|
|
if nval > int(data):
|
|
print(nval)
|
|
break
|