You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
2.8 KiB
Python

from pprint import pprint
from copy import deepcopy
from time import sleep
from asciimatics.screen import Screen
from random import randint
m = []
fix_map = {
'\n': ' ',
'^': '|',
'v': '|',
'>': '-',
'<': '-'
}
r_turns = { '^': '>', '>': 'v', 'v': '<', '<': '^' }
l_turns = { '^': '<', '>': '^', 'v': '>', '<': 'v' }
cart_symbols = ['^', 'v', '>', '<']
carts = []
class Cart:
def __init__(self, x, y, dir):
self.x = x
self.y = y
self.dir = dir
self.turn_counter = 0
@property
def pos(self):
return (self.y, self.x)
def turn_intersection(self):
if self.turn_counter == 0:
self.dir = l_turns[self.dir]
if self.turn_counter == 2:
self.dir = r_turns[self.dir]
self.turn_counter = (self.turn_counter + 1) % 3
def turn_corner(self, corner):
my_map = {
('/', '^'): '>',
('/', '>'): '^',
('/', 'v'): '<',
('/', '<'): 'v',
('\\', '^'): '<',
('\\', '>'): 'v',
('\\', 'v'): '>',
('\\', '<'): '^',
}
self.dir = my_map[(corner, self.dir)]
def move(self):
if self.dir == '^':
self.y -= 1
elif self.dir == '>':
self.x += 1
elif self.dir == 'v':
self.y += 1
elif self.dir == '<':
self.x -= 1
symbol = m[self.y][self.x]
if symbol in ['/', '\\']:
self.turn_corner(symbol)
if symbol == '+':
self.turn_intersection()
with open('input.txt', 'r') as f:
for y, line in enumerate(f.readlines()):
row = []
for x, symbol in enumerate(line):
row.append(fix_map.get(symbol) or symbol)
if symbol in cart_symbols:
carts.append(Cart(x, y, symbol))
m.append(row)
def print_map(screen):
m_cpy = deepcopy(m)
for cart in carts:
m_cpy[cart.y][cart.x] = cart.dir
for i, row in enumerate(m_cpy):
screen.print_at(''.join(row), 0, i)
def anim(screen):
while 1:
carts.sort(key=lambda x: x.pos)
for cart in carts:
cart.move()
# sleep(1)
print_map(screen)
ev = screen.get_key()
if ev in (ord('Q'), ord('q')):
return
screen.refresh()
# Screen.wrapper(anim)
def collision_detection():
coords = [cart.pos for cart in carts]
if len(set(coords)) != len(coords):
return [pos for pos in coords if coords.count(pos) > 1][0]
def get_collision():
while 1:
carts.sort(key=lambda x: x.pos)
for cart in carts:
cart.move()
if collision_detection():
return collision_detection()
col = get_collision()
print(f'{col[1]},{col[0]}')