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

6 years ago
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]}')