2018/Day13/Day13A.py

140 lines
3.6 KiB
Python

import fileinput
import numpy
DIRS = ["^", ">", "v", "<"]
NORTH = 0
EAST = 1
SOUTH = 2
WEST = 3
TURN_LEFT = 0
TURN_STRAIGHT = 1
TURN_RIGHT = 2
carts = 0
cart_pos = []
cart_dirs = []
cart_turns = []
def get_cart(x, y):
try:
pos = cart_pos.index((x, y))
return pos
except ValueError:
raise IndexError
def move_cart(cart, dx, dy):
x, y = cart_pos[cart]
cart_pos[cart] = (x + dx, y + dy)
def remove_cart(cart):
global carts
carts -= 1
cart_pos.pop(cart)
cart_dirs.pop(cart)
cart_turns.pop(cart)
def add_cart(x, y, dir_, turn=TURN_LEFT):
global carts
carts += 1
cart_pos.append((x, y))
cart_dirs.append(dir_)
cart_turns.append(turn)
def print_field(field):
for y, row in enumerate(field):
for x, value in enumerate(row.decode("ascii")):
try:
cart = get_cart(x, y)
print("\033[31;1;4m" + DIRS[cart_dirs[cart]], end="\033[0m")
if value == '-':
print("\u0335", end="")
elif value == '|':
print("\u20D2", end="")
except IndexError:
print(value, end="")
print()
print()
for cart in range(carts):
x, y = cart_pos[cart]
dir_ = DIRS[cart_dirs[cart]]
turn = cart_turns[cart]
print(f"- ({x:>3d}, {y:>3d}) {dir_} {turn}")
print()
inp = []
for y, line in enumerate(fileinput.input()):
row = []
for x, value in enumerate(line.rstrip("\n")):
if value == "^": add_cart(x, y, NORTH); row.append("|")
elif value == ">": add_cart(x, y, EAST); row.append("-")
elif value == "v": add_cart(x, y, SOUTH); row.append("|")
elif value == "<": add_cart(x, y, WEST); row.append("-")
else:
row.append(value)
inp.append(row)
field = numpy.chararray((len(inp), len(inp[0])))
field[:] = inp
one_more = False
def step():
# Move the carts
order = sorted(range(carts), key=lambda cart: cart_pos[cart], reverse=True)
while order:
cart = order.pop()
if cart_dirs[cart] == NORTH: move_cart(cart, 0, -1)
elif cart_dirs[cart] == EAST: move_cart(cart, 1, 0)
elif cart_dirs[cart] == SOUTH: move_cart(cart, 0, 1)
elif cart_dirs[cart] == WEST: move_cart(cart, -1, 0)
value = field[cart_pos[cart][::-1]]
if value == b"+":
cart_dirs[cart] += cart_turns[cart] - 1
cart_dirs[cart] %= 4
cart_turns[cart] = (cart_turns[cart] + 1) % 3
elif value == b"/":
if cart_dirs[cart] in (NORTH, SOUTH):
cart_dirs[cart] = (cart_dirs[cart] + 1) % 4
else:
cart_dirs[cart] = (cart_dirs[cart] - 1) % 4
elif value == b"\\":
if cart_dirs[cart] in (EAST, WEST):
cart_dirs[cart] = (cart_dirs[cart] + 1) % 4
else:
cart_dirs[cart] = (cart_dirs[cart] - 1) % 4
elif value not in (b"-", b"|"):
raise ValueError(value)
u, c = numpy.unique(cart_pos, axis=0, return_counts=True)
if len(u[c > 1]):
for pos in u[c > 1]:
print("crash at", pos)
print(order)
cart = get_cart(*pos)
order = [x if x < cart else x - 1 for x in order if x != cart]
remove_cart(cart)
cart = get_cart(*pos)
order = [x if x < cart else x - 1 for x in order if x != cart]
remove_cart(cart)
print(order)
if carts == 1:
print(cart_pos[0])
return False
return True
print_field(field)
while step():
pass