71 lines
2.3 KiB
Python
Executable File
71 lines
2.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
from useful import *
|
|
|
|
seedstr, rest = headerfooter(open(0))
|
|
seeds = numbers(seedstr)
|
|
|
|
def getmap(l):
|
|
"""
|
|
{'fertilizer': ('water', [[49, 53, 8], ...
|
|
"""
|
|
name, rest = l.split(' map:\n')
|
|
source, _, dest = name.split('-')
|
|
trips = batched(numbers(rest), 3)
|
|
return source, (dest, list(trips))
|
|
|
|
guide = {k: v for (k, v) in (getmap(p) for p in pgphs(rest))} # ugh
|
|
|
|
def move(origin, kart):
|
|
for dst, src, size in kart:
|
|
if src <= origin < src + size:
|
|
return origin + dst - src
|
|
return origin
|
|
|
|
def ship(element, target, origin): # ship('seed', 'light', 42)
|
|
if element == target:
|
|
return origin
|
|
dest, kart = guide[element]
|
|
return ship(dest, target, move(origin, kart))
|
|
|
|
def chop(origin, kart):
|
|
bego, leno = origin
|
|
endo = bego + leno
|
|
if not leno:
|
|
return []
|
|
if not kart:
|
|
return origin,
|
|
dst, src, size = kart[0]
|
|
"""
|
|
how generically can we do this?
|
|
well, when we chop the thing, there's at most going to be
|
|
- something < dst
|
|
- something inside dst (to be transformed)
|
|
- something >= dst+size
|
|
simply grab these three chunks, and recurse on the first and last.
|
|
(something already transformed obviously shouldn't be transformed back)
|
|
"""
|
|
before = (bego, min(endo, src)) if bego < src else (0, 0)
|
|
after = (max(bego, src+size), endo) if src + size < endo else (0, 0)
|
|
inside = (max(bego, src), min(endo, src+size)) if not endo <= src or bego >= src+size else (0, 0)
|
|
during = inside if inside[1] > inside[0] else (0, 0)
|
|
bl = before[0], before[1]-before[0]
|
|
dl = during[0]+dst-src, during[1]-during[0]
|
|
al = after[0], after[1]-after[0]
|
|
return (a for a in (*chop(bl, kart[1:]),
|
|
dl,
|
|
*chop(al, kart[1:])) if a[0] >= 0 and a[1] > 0)
|
|
|
|
def twoship(element, target, origin, indent=0): # ship('seed', 'light', (420, 69))
|
|
if len(sys.argv) > 1 and sys.argv[1] == '-v':
|
|
print(' ' * indent, element, origin)
|
|
if element == target:
|
|
return origin
|
|
dest, kart = guide[element]
|
|
bis = [twoship(dest, target, c, indent+1) for c in chop(origin, kart)]
|
|
return bis
|
|
|
|
print(min(ship('seed', 'location', s) for s in seeds))
|
|
print(min(beg for (beg, sz) in batched(
|
|
collapse([twoship('seed', 'location', p) for p in batched(seeds, 2)]), 2)))
|