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:
deque
#!/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] for line in track_file.read().splitlines() ] 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)
Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink.
Hide child comments as well
Confirm
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
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: