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