In [24]:
import numpy as np
In [25]:
def parse(fn):
levels = []
with open(fn, 'rt') as f:
for l in f.readlines():
levels.append(l.rstrip('\n'))
return levels
In [69]:
class BluePrint:
def __init__(self, fn):
self.tracks = {}
self.carts = []
levels = parse(fn)
under = dict(zip('^v<>|-/\\+ ', '||--|-/\\+ '))
for j, lev in enumerate(levels):
lev = list(lev)
for i, c in enumerate(lev):
pos = (i, j)
if c in '^>v<':
self.carts.append(Cart(pos, c))
self.tracks[pos] = under[c]
class Cart:
def __init__(self, pos, face):
self.pos = pos
self.face = face
self.turn = 'l'
def step(self):
clockwise = [[0,-1],[1,0],[0,1],[-1,0]]
moves = dict(zip('^>v<', map(np.array, clockwise)))
left = dict(zip('^<v>', '<v>^'))
right = dict(zip('^>v<', '>v<^'))
straight = dict(zip('^<v>', '^<v>'))
turn = dict(zip('lsr', [left, straight, right]))
next_turn = dict(zip('lsr', 'srl'))
corner = {'/': dict(zip('^>v<', '>^<v')), '\\': dict(zip('^>v<', '<v>^'))}
self.pos = tuple(np.array(self.pos) + moves[self.face])
new = blueprint.tracks[self.pos]
if new == '+':
self.face = turn[self.turn][self.face]
self.turn = next_turn[self.turn]
if new in ['/', '\\']:
self.face = corner[new][self.face]
def first_collision():
carts = blueprint.carts
keep_moving = True
while keep_moving:
carts = sorted(carts, key=lambda x: x.pos[::-1])
counter = len(carts)
current = list(map(lambda x: x.pos, carts))
while counter > 0:
cart = carts.pop(0)
current.pop(0)
cart.step()
carts.append(cart)
if cart.pos in current:
print(','.join(map(str, cart.pos)))
keep_moving = False
break
else:
current.append(cart.pos)
counter -= 1
In [80]:
blueprint = BluePrint('input_test1.txt')
first_collision()
In [81]:
blueprint = BluePrint('input.txt')
first_collision()
In [87]:
def cartnage():
carts = blueprint.carts
while len(carts) > 1:
carts = sorted(carts, key=lambda x: x.pos[::-1])
tick = [1 for x in carts]
current = list(map(lambda x: x.pos, carts))
while sum(tick) > 0:
cart = carts.pop(0)
current.pop(0)
tick.pop(0)
cart.step()
if cart.pos in current:
indices = [i for i, c in enumerate(carts) if c.pos != cart.pos]
carts = [carts[i] for i in indices]
tick = [tick[i] for i in indices]
current = [x.pos for x in carts]
else:
current.append(cart.pos)
carts.append(cart)
tick.append(0)
print(','.join(map(str, cart.pos)))
In [88]:
blueprint = BluePrint('input_test2.txt')
cartnage()
In [89]:
blueprint = BluePrint('input.txt')
cartnage()