Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Cart:
- STATES = [-1, 0, 1]
- MOVEMENT_INSTRUCTIONS = {'^': 3, 'v': 1, '<': 2,
- '>': 0}
- def __init__(self, pos, sign, raw_map):
- self.raw_map = raw_map
- map_width = len(raw_map.split('\n')[0]) + 1
- self.directions = [1, map_width, -1, -map_width]
- self.pos = pos
- self.state = 0
- self.direction = self.MOVEMENT_INSTRUCTIONS[sign]
- def intersect(self):
- state = self.state % 3
- self.direction = (self.direction + self.STATES[state] + 4) % 4
- self.state = (state + 1) % 3
- def move(self):
- self.pos += self.directions[self.direction]
- track = self.raw_map[self.pos]
- if track in ['\\', '/']:
- self.corner(track)
- elif track == '+':
- self.intersect()
- def corner(self, track):
- if track == '/':
- if self.direction == 0:
- self.direction = 3
- elif self.direction == 1:
- self.direction = 2
- elif self.direction == 2:
- self.direction = 1
- elif self.direction == 3:
- self.direction = 0
- else:
- print(self.direction)
- raise ValueError
- else:
- if self.direction == 2:
- self.direction = 3
- elif self.direction == 3:
- self.direction = 2
- elif self.direction == 1:
- self.direction = 0
- elif self.direction == 0:
- self.direction = 1
- else:
- print(self.direction)
- print(track)
- raise ValueError
- def find_solutions(raw_map, return_on_first_collision=False):
- carts = {}
- map_width = len(raw_map.split('\n')[0]) + 1
- for pos, c in enumerate(raw_map):
- if c in '<>^v':
- carts[pos] = Cart(pos, c, raw_map)
- # MAP_RAW = [c for c in MAP_RAW if c != '\n']
- round_counter = 0
- collision = 0
- while len(carts) > 1:
- current_carts = sorted(carts.keys())
- for cart_pos in current_carts:
- try:
- cart = carts[cart_pos]
- except KeyError:
- continue
- cart.move()
- del carts[cart_pos]
- new_pos = cart.pos
- if new_pos in carts:
- collision += 1
- if collision == 1:
- first_collision_coordinates = (
- new_pos % map_width, new_pos // map_width)
- print('First collision : {},{}'.format(
- *first_collision_coordinates
- )
- )
- if return_on_first_collision:
- return first_collision_coordinates
- del carts[new_pos]
- else:
- carts[new_pos] = cart
- round_counter += 1
- try:
- try:
- remaining_cart = carts.keys()[0]
- except TypeError: # Python3 .keys() is not a list
- remaining_cart = list(carts.keys())[0]
- remaining_cart_coordinates = (remaining_cart % map_width,
- remaining_cart // map_width)
- print('Last remaining cart: {},{}'.format(*remaining_cart_coordinates))
- return remaining_cart_coordinates
- except IndexError:
- print('No carts left after the last collision!')
- return None
- if __name__ == '__main__':
- from input_day13 import raw
- #
- MAP_RAW = raw
- map = [[c for c in line] for line in MAP_RAW.split('\n') if line]
- test_map_part1 = r"""/->-\
- | | /----\
- | /-+--+-\ |
- | | | | v |
- \-+-/ \-+--/
- \------/ """
- test_map_part2 = r"""/>-<\
- | |
- | /<+-\
- | | | v
- \>+</ |
- | ^
- \<->/"""
- assert find_solutions(test_map_part1, return_on_first_collision=True) == (7, 3)
- assert find_solutions(test_map_part2) == (6, 4)
- find_solutions(MAP_RAW)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement