Advertisement
Guest User

AoC 2022 - Day 23

a guest
Jan 3rd, 2023
454
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.91 KB | None | 0 0
  1. """
  2. Advent of Code 2022 Day 23
  3. """
  4. import sys
  5.  
  6. from advent_tools import get_daily_input
  7.  
  8. DAY = 23
  9.  
  10. TEST = sys.argv[1] == "test" if len(sys.argv) > 1 else False
  11.  
  12. TEST_DATA = """
  13. ....#..
  14. ..###.#
  15. #...#.#
  16. .#...##
  17. #.###..
  18. ##.#.##
  19. .#..#..
  20. """
  21.  
  22. if TEST:
  23.     def get_daily_input(_):
  24.         for line in TEST_DATA.strip().split("\n"):
  25.             yield line.strip("\n")
  26.  
  27.  
  28. def load_data() -> dict[tuple[int, int], list[tuple[int, int]]]:
  29.     data = {}
  30.     x = 0
  31.     for l in get_daily_input(DAY):
  32.         y = 0
  33.         for c in l:
  34.             if c == "#":
  35.                 data[x, y] = [(x, y)]
  36.             y += 1
  37.         x += 1
  38.     return data
  39.  
  40.  
  41. def count_empty(map_data: dict[tuple[int, int], list[tuple[int, int]]]) -> int:
  42.     h = max([k[0] for k in map_data]) - min([k[0] for k in map_data]) + 1
  43.     w = max([k[1] for k in map_data]) - min([k[1] for k in map_data]) + 1
  44.     return h * w - len(map_data)
  45.  
  46.  
  47. def make_moves(map_data: dict[tuple[int, int], list[tuple[int, int]]], rule_order: str)\
  48.         -> dict[tuple[int, int], list[tuple[int, int]]]:
  49.     proposed_moves: dict[tuple[int, int], list[tuple[int, int]]] = {}
  50.  
  51.     for i, j in map_data:
  52.         proposed_moves[i, j] = [(i, j)]
  53.         surroundings: dict[str, tuple[bool, tuple[int, int]]] = {}
  54.         for direction in ["N", "NE", "E", "SE", "S", "SW", "W", "NW"]:
  55.             r = i + (1 if "S" in direction else -1 if "N" in direction else 0)
  56.             d = j + (1 if "E" in direction else -1 if "W" in direction else 0)
  57.             surroundings[direction] = map_data.get((r, d), False), (r, d)
  58.         if any([surroundings[k][0] for k in surroundings]):
  59.             for direction in rule_order:
  60.                 if not any(
  61.                         [surroundings[k][0] for k in surroundings if direction in k]):
  62.                     proposed_moves[surroundings[direction][1]] = \
  63.                         proposed_moves.get(surroundings[direction][1], []) + [(i, j)]
  64.                     del proposed_moves[(i, j)]
  65.                     break
  66.  
  67.     for k, v in [(a, b) for (a, b) in proposed_moves.items()]:
  68.         if len(v) > 1:
  69.             for i in v:
  70.                 proposed_moves[i] = [i]
  71.             del proposed_moves[k]
  72.  
  73.     return proposed_moves
  74.  
  75.  
  76. def part_1() -> int:
  77.     map_data = load_data()
  78.     rule_order = "NSWE"
  79.     for i in range(10):
  80.         map_data = make_moves(map_data, rule_order)
  81.         rule_order = rule_order[1:] + rule_order[0]
  82.     return count_empty(map_data)
  83.  
  84.  
  85. def part_2() -> int:
  86.     map_data = load_data()
  87.     prev_map_data = {}
  88.     rule_order = "NSWE"
  89.     i = -1
  90.     while prev_map_data != map_data:
  91.         prev_map_data = map_data
  92.         map_data = make_moves(map_data, rule_order)
  93.         rule_order = rule_order[1:] + rule_order[0]
  94.         i += 1
  95.     return i
  96.  
  97.  
  98. def main():
  99.     print(f"Part 1: {part_1()}")
  100.     print(f"Part 2: {part_2()}")
  101.  
  102.  
  103. if __name__ == "__main__":
  104.     main()
  105.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement