From 0327a3f36aa284d3fe7dadc425b65f62ea2f6d9d Mon Sep 17 00:00:00 2001 From: Mikael CAPELLE Date: Fri, 23 Dec 2022 09:43:32 +0100 Subject: [PATCH] Add day 23. --- 2022/day23.py | 102 ++++++++++++++++++++++++++++++++++++++++++ 2022/inputs/day23.txt | 70 +++++++++++++++++++++++++++++ 2022/tests/day23.txt | 7 +++ 3 files changed, 179 insertions(+) diff --git a/2022/day23.py b/2022/day23.py index dbb8408..02c9235 100644 --- a/2022/day23.py +++ b/2022/day23.py @@ -1,3 +1,105 @@ # -*- encoding: utf-8 -*- +import itertools import sys +from collections import defaultdict + +Directions = list[ + tuple[ + str, tuple[int, int], tuple[tuple[int, int], tuple[int, int], tuple[int, int]] + ] +] + +# (Y, X) +DIRECTIONS: Directions = [ + ("N", (-1, 0), ((-1, -1), (-1, 0), (-1, 1))), + ("S", (1, 0), ((1, -1), (1, 0), (1, 1))), + ("W", (0, -1), ((-1, -1), (0, -1), (1, -1))), + ("E", (0, 1), ((-1, 1), (0, 1), (1, 1))), +] + + +def min_max_yx(positions: set[tuple[int, int]]) -> tuple[int, int, int, int]: + ys, xs = {y for y, x in positions}, {x for y, x in positions} + return min(ys), min(xs), max(ys), max(xs) + + +def print_positions(positions: set[tuple[int, int]]): + min_y, min_x, max_y, max_x = min_max_yx(positions) + print( + "\n".join( + "".join( + "#" if (y, x) in positions else "." for x in range(min_x - 1, max_x + 2) + ) + for y in range(min_y - 1, max_y + 2) + ) + ) + + +def round( + positions: set[tuple[int, int]], + directions: Directions, +): + to_move: dict[tuple[int, int], list[tuple[int, int]]] = defaultdict(lambda: []) + for (y, x) in positions: + elves = { + (dy, dx): (y + dy, x + dx) in positions + for dy, dx in itertools.product((-1, 0, 1), (-1, 0, 1)) + if (dy, dx) != (0, 0) + } + + if not any(elves.values()): + to_move[y, x].append((y, x)) + continue + + found: str | None = None + for d, (dy, dx), d_yx_check in directions: + if not any(elves[dy, dx] for dy, dx in d_yx_check): + found = d + to_move[y + dy, x + dx].append((y, x)) + break + if found is None: + to_move[y, x].append((y, x)) + + positions.clear() + for ty, tx in to_move: + if len(to_move[ty, tx]) > 1: + positions.update(to_move[ty, tx]) + else: + positions.add((ty, tx)) + + directions.append(directions.pop(0)) + + +POSITIONS = { + (i, j) + for i, row in enumerate(sys.stdin.read().splitlines()) + for j, col in enumerate(row) + if col == "#" +} + +# === part 1 === + +p1, d1 = POSITIONS.copy(), DIRECTIONS.copy() +for r in range(10): + round(p1, d1) + +min_y, min_x, max_y, max_x = min_max_yx(p1) +answer_1 = sum( + (y, x) not in p1 for y in range(min_y, max_y + 1) for x in range(min_x, max_x + 1) +) +print(f"answer 1 is {answer_1}") + +# === part 2 === + +p2, d2 = POSITIONS.copy(), DIRECTIONS.copy() +answer_2 = 0 +while True: + answer_2 += 1 + backup = p2.copy() + round(p2, d2) + + if backup == p2: + break + +print(f"answer 2 is {answer_2}") diff --git a/2022/inputs/day23.txt b/2022/inputs/day23.txt index e69de29..399143d 100644 --- a/2022/inputs/day23.txt +++ b/2022/inputs/day23.txt @@ -0,0 +1,70 @@ +#...#.####.......###.#..##.#####.#...##.##.##.#.#.#...#.#...##...#..#. +#.#.####.#.#.###...#####.##..####..#.###...#.#...........#..#.#..##... +#.#####....#..###.#.###..##.#.#.#..#...###...####.#.##.#.#..#.###.#..# +.#..##.....##.##.#.#...##.#.##..#..##.#.#...#####...####..###...##..#. +##...###..##....##.#.#...#...#...##...#..#.#..##..###..##......####.#. +#..##.#.#...####.....###.#...#####.....##.##.#....#.#.......####..#.#. +..#.###....###..##.....#...#...#####....#.###.....###..###.#####..#... +#..###..##...##.#.#...##.#.#.#.###.#######.#.###...#..#.######....##.# +#.....###.....####.#..#...##..#.#.#...##....##.###.#.#...#.#.#..#.###. +.#...#......#......##..##.#....#.......##....##...#####...###..#.#.### +.#.####...#.###.##..##.#.#.##.##.####..####.###.#######..##...#..###.. +.....##......#.#.##.######....#.#.#.#####.##.#.##...#.#..###.#.#.###.. +.#.##.#.#.##..###.#..#...#####..##..#.#####...#....#..#.#...#.##.#.... +.####...#....#.#.##.#.##.####......#......###....####.....#######....# +.###...########.##.#..#.#...#.##..####.##.#####.#..#.#....##...#...##. +#..###..####.#....#.#..#####.##.#.##...#.#.###.###.#.#....###...#.##.# +###..#.###.#.#####.###....###..#...##.###.#..##.####.#.#.#.###...##.#. +.#####.#..##..#...#.##.#..##.#.#.#...##.##..####..#.##.........#..##.# +.#.###...#....#.##.######..#...##.#...###.##...###...########..#.#.### +.######.#...##.####.##..#..#...#.#..##.##.#.##.#.#.#.##.#.###..##.##.# +#...####.#.#..##.#...##.#.#...##.#......####...#..#....##.##..#.###.#. +#....##..#.##....#######.#...#..#.####.##.....###.####.#.###..#..####. +..##..##.#....########..#.##.......#...#.#.........##.#.#..#....####.. +.#..##.#.#.##...#.....##...##.#.#...#....#..#####.#..#..#.###..#.#.### +#.##.##............##.##.....##.#...#.#..##..#.#..###.....#..#..#..#.# +..#.....#..#..#.#.....#...###.#.#..#....##.##...#...##.##....#..##...# +..##...##.##......#...#..#####....#..#......###.#..#####...####.#....# +#..###.##..####.#....#..##.#..##.##.#.#..######.........#.##....###### +..#.######.#.##...#..####..##....##..###.#.###.#.#..#.##.##.###.#..#.# +..#.####.###.#.#..###..#######.#..##.#....#.#####.###....#.#..###...## +....#....#..###.#...#......#..##...##..##.#.###...###.#.#.#.#..#...#.# +#....#..##..##.###.####.#######.###.###...#...#..###...#...#.#..#.##.# +#...###.##..#.#..#.#..#.#.#..###..####.##.##.#...###.#.###########...# +##...#...#...#..##....#...#...#....###.#######.....#.#.##...##..#.#..# +.....##.##.#.#.#..#..###....##.#....####.#.##.####..#.##.#..##.##.###. +....##.#....#####.#.##.........##.######.#..###..###..#.#.##.###.....# +...##..#####....##..####....##..###.##.##..##...#.#.###.#.#.##.#.##... +..#..####.#..#.##.##.#..####..#.#...##.....#...#....###..#.#.##..#.##. +#####.#..#.#.###..#.#.###.#######.#.#...#........##..#...#.##..#.##.#. +.#..###.###.#..##.####.##.###...#..#.#.....#.#.#...#....#.###..##.#.#. +.#.#.....##.##.#.####..##.#.#...#.#..#.....#..#....#......#.######.##. +...##.##..#....###...#..#.#..#.#.#.##..##.#..#.####..####.#.#......... +#.###.#...#....#...#.###.....#..#...##.#.#.####..#...#.#.#..####...... +##.###.#.#####.#.##....#..#..##..##..#..##..##...#.#.##.##....#...##.. +.###..###....#...##..###..#....###.....#..##...###.###.###..##.#..#### +#.###........#..##.#.....#.....#...##.#####.#.##..##....####.#...##.#. +#.#.#..###.##.###..###..##..######..##.#####......#.##....##.#..###.#. +###...##.#.#.#.#.#.######...#..##.....#.#######.#..#..###.#.###.#...#. +###..######......#.###..#.....#########....#####.##..#...#.#...###..## +##.#..######..#.###..#.###.###.#.#####.####.....#...#.#...#####.#..##. +...####.#.#####.##...##..#.######.###....#.###.#.##.#####...#.#.#.#### +#..###.########.#.###.#.####.###.###.#..#.##.#.#####..####.#.###...### +#..#.....#.###.#.##.###.#.....#..#....#####.#.#...##.###.######.###.## +##.#.#...###.#.#..#.#.###....###..#.##.#..#..###.#..#######.##.###.### +.##..##.#..#.#####.###.#.#.#......#.#.##.#...#.######.##...#.###.##### +#####....#.##....##.###..#.###..###.##...####.###.###..##.####.#.##.## +#......#.##.##.##.#....#.##.##..########.#....#..#..###.#####.#.#..##. +.#..#...#..##.#..###...#......##.##.###.....#.#.#.#..#.#####.##..#.### +.##.##.#.##.###..#..##.####.#.#..####.#.#.......##.......##.....#####. +####...##...#.#.#..###.#####.#.#.#.##.#..##......#.###.##..#...#...#.# +...........##.#.####.#.#########..###....#...#.......#..####..#####.#. +.#.###.##.#..####..#.###.#.#####..##.#......#.#..#####.##.#.###.#.##.# +###..#...#.##.####.#.##...#..#.......######...#....##....#.....#...#.. +####.#.#...#.#.#######.##...#..#.#..#####...#..#.#..##.##.....##.##.#. +###..##..#..#.#.##.##..#..##..##..#####.#.##..##.####.##.##...#.####.# +#.##.#.#..##..####.....#.###..#....###.#.##.###.#.#.#.######.##....#.. +.#.#..##..#.###.#.....##.##..##....####..#.#..#..##########.#...#...#. +###.####.#.#.##.#......#.###......##.###..##.##.#..#....#.##.#..#..... +.....##.......###.#..####.#.#.#.###..##...##...####.#.##.#.#.#..#.#.## +..##.##.#..#.##.....#...##.#...#.###..##.#.##...#..#.....###.#.#####.. diff --git a/2022/tests/day23.txt b/2022/tests/day23.txt index e69de29..14005cf 100644 --- a/2022/tests/day23.txt +++ b/2022/tests/day23.txt @@ -0,0 +1,7 @@ +....#.. +..###.# +#...#.# +.#...## +#.###.. +##.#.## +.#..#..