diff --git a/day21.py b/day21.py new file mode 100644 index 0000000..162c226 --- /dev/null +++ b/day21.py @@ -0,0 +1,94 @@ +from tools.aoc import AOCDay +from tools.coordinate import Coordinate +from tools.grid import Grid, GridTransformation +from typing import Any + + +FLIPS = [ + GridTransformation.ROTATE_RIGHT, + GridTransformation.ROTATE_RIGHT, + GridTransformation.ROTATE_RIGHT, + GridTransformation.ROTATE_RIGHT, + GridTransformation.FLIP_HORIZONTALLY, + GridTransformation.ROTATE_RIGHT, + GridTransformation.ROTATE_RIGHT, + GridTransformation.ROTATE_RIGHT, +] + + +def init_grid() -> Grid: + grid = Grid() + grid.set(Coordinate(1, 0)) + grid.set(Coordinate(2, 1)) + grid.set(Coordinate(0, 2)) + grid.set(Coordinate(1, 2)) + grid.set(Coordinate(2, 2)) + return grid + + +class Day(AOCDay): + inputs = [ + [ + (12, "input21_test"), + (176, "input21") + ], + [ + (2368161, "input21") + ] + ] + + def load_replacement_grids(self) -> dict: + ret = {} + for line in self.getInput(): + rep, grid_string = line.split(" => ") + ret[rep] = Grid.from_str(grid_string, true_char='#') + rep_grid_size = len(rep.split("/")[0]) + 1 + ret[rep].minX, ret[rep].maxX, ret[rep].minY, ret[rep].maxY = 0, rep_grid_size, 0, rep_grid_size + + return ret + + def interact(self, interact_count: int) -> int: + grid = Grid.from_str('.#./..#/###') + grid_size = 3 + replacements = self.load_replacement_grids() + + for i in range(2 if self._current_test_file.endswith('test') else interact_count): + new_grid = Grid() + block_size = 3 + replace_size = 4 + if grid_size % 2 == 0: + block_size = 2 + replace_size = 3 + + for x in range(0, grid_size, block_size): + for y in range(0, grid_size, block_size): + sub_grid = grid.sub_grid(x, y, x + block_size - 1, y + block_size - 1) + sub_grid.minX, sub_grid.minY, sub_grid.maxX, sub_grid.maxY = 0, 0, block_size - 1, block_size - 1 + for f in FLIPS: + sub_grid.transform(f) + sub_grid.maxX, sub_grid.maxY = block_size - 1 + sub_grid.minX, block_size - 1 + sub_grid.minY + if str(sub_grid) in replacements: + new_grid.update( + x // block_size * replace_size, + y // block_size * replace_size, + replacements[str(sub_grid)] + ) + break + else: + raise ValueError("No sub_grid matches found.") + + grid = new_grid + grid_size = grid_size // block_size * replace_size + + return grid.getOnCount() + + def part1(self) -> Any: + return self.interact(5) + + def part2(self) -> Any: + return self.interact(18) + + +if __name__ == '__main__': + day = Day(2017, 21) + day.run(verbose=True) diff --git a/inputs/input21 b/inputs/input21 new file mode 100644 index 0000000..6bb054b --- /dev/null +++ b/inputs/input21 @@ -0,0 +1,108 @@ +../.. => .#./.../### +#./.. => .#./##./#.. +##/.. => #.#/#../### +.#/#. => ##./..#/### +##/#. => .#./#../..# +##/## => #../..#/#.# +.../.../... => .###/.#.#/.###/##.# +#../.../... => .##./##../##../#.## +.#./.../... => .#.#/#.#./..#./..#. +##./.../... => ###./#.##/...#/#.## +#.#/.../... => .#.#/.#../.###/.### +###/.../... => ..##/#.#./..../##.# +.#./#../... => #.../..../..../.... +##./#../... => ...#/..#./.###/#.#. +..#/#../... => #.../#.##/###./##.. +#.#/#../... => .##./#..#/#..#/..## +.##/#../... => .#.#/#.##/..##/.#.# +###/#../... => #.#./.###/..#./#.#. +.../.#./... => #..#/..../.##./.#.# +#../.#./... => .#../.##./.#.#/...# +.#./.#./... => ##.#/...#/.##./...# +##./.#./... => ..#./#.#./#.##/#### +#.#/.#./... => ..##/#..#/.###/.... +###/.#./... => .#../#..#/#.../..#. +.#./##./... => ..##/#.#./####/###. +##./##./... => ...#/.#../####/#..# +..#/##./... => ..##/##../###./.... +#.#/##./... => ..##/#.../.#../.##. +.##/##./... => #.../##../#.##/...# +###/##./... => .#../####/#.##/#.## +.../#.#/... => #..#/####/###./#.#. +#../#.#/... => #.../##.#/#.../.#.. +.#./#.#/... => ##.#/##.#/..#./..#. +##./#.#/... => .###/..#./.#../.### +#.#/#.#/... => .###/##../..#./..#. +###/#.#/... => ##../.#../.#../.#.. +.../###/... => ..#./#.#./..#./#..# +#../###/... => ..../#.#./##.#/..## +.#./###/... => ..#./#.#./..##/.#.. +##./###/... => .##./..##/#..#/#.#. +#.#/###/... => ###./###./#.##/..## +###/###/... => ##.#/..../.##./.#.. +..#/.../#.. => .###/####/..../##.# +#.#/.../#.. => ##../###./#..#/...# +.##/.../#.. => ###./#..#/###./...# +###/.../#.. => #.../#..#/##.#/.##. +.##/#../#.. => ..##/####/..##/#... +###/#../#.. => #.../..../...#/..## +..#/.#./#.. => ####/#.#./..../.#.# +#.#/.#./#.. => .##./.#.#/##.#/.##. +.##/.#./#.. => ###./.#.#/###./##.# +###/.#./#.. => #.##/..##/#.#./##.# +.##/##./#.. => ..../..##/#.#./.##. +###/##./#.. => #.#./#..#/#..#/###. +#../..#/#.. => ..../####/#..#/.### +.#./..#/#.. => .###/#.../#.../#.## +##./..#/#.. => ####/##.#/###./#### +#.#/..#/#.. => .#../##.#/#..#/#..# +.##/..#/#.. => ..##/##.#/#.##/###. +###/..#/#.. => ##.#/####/##.#/.#.. +#../#.#/#.. => .###/#..#/.##./.### +.#./#.#/#.. => #.##/.##./.#../..#. +##./#.#/#.. => ###./..#./.##./##.. +..#/#.#/#.. => .###/.#.#/#.#./##.. +#.#/#.#/#.. => #..#/.###/.##./.... +.##/#.#/#.. => ###./.###/#.##/.### +###/#.#/#.. => ####/.###/..../.##. +#../.##/#.. => ##.#/..../#.../..#. +.#./.##/#.. => #.../..../...#/###. +##./.##/#.. => ###./.#../..##/...# +#.#/.##/#.. => #.../...#/..#./.### +.##/.##/#.. => ###./..../##.#/...# +###/.##/#.. => ##.#/##../###./.##. +#../###/#.. => ..#./#.../..##/#.## +.#./###/#.. => ...#/.##./.#../.#.. +##./###/#.. => ##.#/.#.#/###./.... +..#/###/#.. => #.##/#.../####/.##. +#.#/###/#.. => .#.#/...#/#..#/..#. +.##/###/#.. => .##./#..#/#..#/.#.# +###/###/#.. => ###./####/#.##/#... +.#./#.#/.#. => ###./#..#/...#/...# +##./#.#/.#. => #.#./#.##/#.../#..# +#.#/#.#/.#. => .#.#/#.##/..../.#.. +###/#.#/.#. => #.#./.#../.###/#.#. +.#./###/.#. => #.../.###/##../##.# +##./###/.#. => .###/#.../####/.#.# +#.#/###/.#. => #..#/####/#.#./#... +###/###/.#. => .#../..../.##./.#.# +#.#/..#/##. => ##../###./...#/###. +###/..#/##. => .##./###./.###/#.## +.##/#.#/##. => ..../##.#/#..#/#... +###/#.#/##. => .###/##../..../..#. +#.#/.##/##. => ####/.###/##../...# +###/.##/##. => #.##/..##/..#./#..# +.##/###/##. => ..../#.##/#.../#.## +###/###/##. => ..../#..#/#.##/#.## +#.#/.../#.# => #.../##.#/..../.#.# +###/.../#.# => ##../##../#.#./.##. +###/#../#.# => .##./.#../#.##/.##. +#.#/.#./#.# => #.../.#../####/#.## +###/.#./#.# => .###/##.#/#.../#.#. +###/##./#.# => .##./.##./.###/.#.# +#.#/#.#/#.# => ####/####/###./.##. +###/#.#/#.# => #.#./.###/...#/.#.# +#.#/###/#.# => .###/..#./..../.##. +###/###/#.# => #.#./##.#/..#./..#. +###/#.#/### => ###./#.../##../##.. +###/###/### => ##.#/.#.#/#.#./...# diff --git a/inputs/input21_test b/inputs/input21_test new file mode 100644 index 0000000..53105fb --- /dev/null +++ b/inputs/input21_test @@ -0,0 +1,2 @@ +../.# => ##./#../... +.#./..#/### => #..#/..../..../#..# \ No newline at end of file