### re: AoC Day 13: Mine Cart Madness VIEW POST

This one seemed like the hardest one so far on first reading, but I ended up grasping it better than a couple of the previous puzzles. I ended up using a `deque` to make the turning directions easier to muck with:

``````#!/usr/bin/env python

from collections import deque

class Cart:
def __init__(self, x, y, current_direction):
self.x = x
self.y = y
self.current_direction = current_direction
self.num_intersections_reached = 0
self.directions = deque(['<', 'v', '>', '^'])
self.collided = False
while self.directions[0] != self.current_direction:
self.directions.rotate()

def move(self):
self.x += 1 if self.current_direction == '>' else -1 if self.current_direction == '<' else 0
self.y += 1 if self.current_direction == 'v' else -1 if self.current_direction == '^' else 0

def turn_left(self):
self.directions.rotate(-1)
self.current_direction = self.directions[0]

def turn_right(self):
self.directions.rotate(1)
self.current_direction = self.directions[0]

def update_direction(self, track):
track_piece = track[self.y][self.x]

if track_piece == '+':
self.num_intersections_reached += 1
self.num_intersections_reached %= 3

if self.num_intersections_reached  == 1:
self.turn_left()
elif self.num_intersections_reached  == 0:
self.turn_right()
elif track_piece == '/':
if self.current_direction in {'^', 'v'}:
self.turn_right()
else:
self.turn_left()
elif track_piece == '\\':
if self.current_direction in {'^', 'v'}:
self.turn_left()
else:
self.turn_right()

def get_next_state(track_state, carts):
carts.sort(key=lambda cart: (cart.y, cart.x))

for cart in carts:
cart.move()
cart.update_direction(track_state)

for other_cart in carts:
if cart != other_cart and cart.x == other_cart.x and cart.y == other_cart.y:
cart.collided = other_cart.collided = True
print(f'Crash: {cart.x},{cart.y}')

carts = [cart for cart in carts if not cart.collided]

return track_state, carts

def run(track_state, carts):
while True:
track_state, carts = get_next_state(track_state, carts)
if len(carts) == 1:
print(f'Last cart standing: {carts[0].x},{carts[0].y}')
return track_state

if __name__ == '__main__':
with open('input.txt') as track_file:
track_state = [
[char for char in line]
]

carts = []
for y, row in enumerate(track_state):
for x, char in enumerate(row):
if char in {'^', 'v', '>', '<'}:
carts.append(Cart(x, y, char))

if char in {'<', '>'}:
track_state[y][x] = '-'
elif char in {'^', 'v'}:
track_state[y][x] = '|'

track_state = run(track_state, carts)
``````
code of conduct - report abuse