def move(direction: str, location: Location) -> Location: if direction == "N": location = Location(location.x, location.y - 1) if direction == "W": location = Location(location.x - 1, location.y) if direction == "S": location = Location(location.x, location.y + 1) if direction == "E": location = Location(location.x + 1, location.y) return location
def test_size_of_fifth_example_map(self): self.assertEqual( 31, scan_input( 3, "^WSSEESWWWNW(S|NENNEEEENN(ESSSSW(NWSW|SSEN)|WSWWN(E|WWS(E|SS))))$" ).size(Location(3, 3)))
def follow_basic_commands(self, location: Location, commands: str) -> Location: for direction in commands: if direction not in ['N', 'W', 'S', 'E']: raise Exception("direction must be in (N, E, S, W) but was: " + direction) self.add_door(direction, location) location = location.move(direction) return location
def scan_input(radius: int, string_input: str) -> Map: brackets = parse_input_for_brackets(string_input) map_layout = initiate_map(radius) locations = {Location(radius, radius)} map_layout.follow_commands(locations, brackets) return map_layout
def scan_input(input_string: str) -> Cave: cave_map = [list(line) for line in input_string.strip().split('\n')] creatures = [] for x in range(len(cave_map)): for y in range(len(cave_map[x])): if cave_map[x][y] == 'E' or cave_map[x][y] == 'G': creatures.append(Creature(cave_map[x][y], Location(y, x))) cave_map[x][y] = '.' return Cave(cave_map, creatures)
def test_small_cave_creatures_can_be_extracted(self): self.assertEqual( scan_input(SMALL_CAVE).creatures, [ Creature('G', Location(2, 1)), Creature('E', Location(4, 1)), Creature('E', Location(1, 2)), Creature('G', Location(3, 2)), Creature('E', Location(5, 2)), Creature('G', Location(2, 3)), Creature('E', Location(4, 3)) ])
def test_locations_can_be_sorted_in_reading_order(self): unsorted_locations = [ Location(2, 2), Location(2, 1), Location(1, 2), Location(1, 1), ] unsorted_locations.sort() unsorted_locations.sort() self.assertEqual(unsorted_locations, [ Location(1, 1), Location(1, 2), Location(2, 1), Location(2, 2), ])
def test_find_potential_destinations(self): subject = Creature('E', Location(1, 1)) self.assertEqual( scan_input(DESTINATION_PRACTICE_CAVE).find_potential_destinations( subject), [ Location(3, 1), Location(5, 1), Location(2, 2), Location(5, 2), Location(1, 3), Location(3, 3) ])
def __tic(self): old_grid = deepcopy(self.grid) for y in range(len(self.grid)): for x in range(len(self.grid[y])): adjecant_loc = filter_outside( Location(y, x).neighbours8(), len(self.grid) - 1) states = [old_grid[loc.x][loc.y] for loc in adjecant_loc] if old_grid[y][x] == '.' and states.count('|') >= 3: self.grid[y][x] = '|' if old_grid[y][x] == '|' and states.count('#') >= 3: self.grid[y][x] = '#' if old_grid[y][x] == '#' and (states.count('#') == 0 or states.count('|') == 0): self.grid[y][x] = '.'
def to_coordinates(room_location: Location) -> Location: return Location(room_location.x * 2 + 1, room_location.y * 2 + 1)
def test_size_of_fourth_example_map(self): self.assertEqual( 23, scan_input( 3, "^ESSWWN(E|NNENN(EESS(WNSE|)SSS|WWWSSSSE(SW|NNNE)))$").size( Location(3, 3)))
map_layout.follow_commands(locations, brackets) return map_layout if __name__ == "__main__": with open("../../data/day20.txt", "r") as file: input_string = file.readline() SIZE = 52 actual_brackets = parse_input_for_brackets(input_string) actual_map_layout = initiate_map(SIZE) initial_locations = {Location(SIZE, SIZE)} actual_map_layout.follow_commands(initial_locations, actual_brackets) print(actual_map_layout) size, distances = actual_map_layout.size(Location(SIZE, SIZE)) print("Part I: longest path is: " + str(size)) number_of_rooms = sum( [rooms for steps, rooms in distances.items() if steps >= 999]) print("Part II: number of rooms more then 1000 doors away " + str(number_of_rooms)) # Part I # 4011 answer is to low -- grid was to small (50) -- grid 52 is perfect
def test_size_of_third_example_map(self): self.assertEqual( 18, scan_input(2, "^ENNWSWW(NEWS|)SSSEEN(WNSE|)EE(SWEN|)NNN$").size( Location(2, 2)))
def test_size_of_second_example_map(self): self.assertEqual( 10, scan_input(2, "^ENWWW(NEEE|SSE(EE|N))$").size(Location(2, 2)))
def test_size_of_small_map(self): self.assertEqual(3, scan_input(1, "^WNE$").size(Location(1, 1)))
def initiate_map(radius: int) -> Map: grid = create_base_grid(radius) start = to_coordinates(Location(radius, radius)) grid[start.y][start.x] = "X" return Map(grid)
def test_find_targets(self): subject = Creature('E', Location(1, 1)) self.assertListEqual( scan_input(DESTINATION_PRACTICE_CAVE).find_targets(subject), [Location(4, 1), Location(2, 3), Location(5, 3)])