Advertisement
Guest User

AoC 2022 Day 23 - Python

a guest
Dec 23rd, 2022
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.91 KB | None | 0 0
  1. class Elf:
  2.     def __init__(self, x: int, y: int):
  3.         self.x, self.y = x,y
  4.         self.next_square = None
  5.  
  6.     def find_next_square(self, elf_set: set[tuple[int, int]], round: int):
  7.         n = (self.x, self.y - 1)
  8.         ne = (self.x+1, self.y - 1)
  9.         nw = (self.x-1, self.y - 1)
  10.         s = (self.x, self.y + 1)
  11.         se = (self.x+1, self.y + 1)
  12.         sw = (self.x-1, self.y + 1)
  13.         e = (self.x+1, self.y)
  14.         w = (self.x-1, self.y)
  15.         if set([n, ne, nw, s, se, sw, e, w]).isdisjoint(elf_set):
  16.             self.next_square = None
  17.             return self.next_square
  18.         options = []
  19.         options.append(n if set([n, ne, nw]).isdisjoint(elf_set) else None)
  20.         options.append(s if set([s, se, sw]).isdisjoint(elf_set) else None)
  21.         options.append(w if set([w, nw, sw]).isdisjoint(elf_set) else None)
  22.         options.append(e if set([e, ne, se]).isdisjoint(elf_set) else None)
  23.         for i in range(4):
  24.             if options[(i + round) % 4] is not None:
  25.                 self.next_square = options[(i + round) % 4]
  26.                 return self.next_square
  27.         return self.next_square
  28.  
  29.     def move(self):
  30.         self.x, self.y = self.next_square
  31.  
  32. def parse(data: str) -> list[Elf]:
  33.     elves = []
  34.     for i, row in enumerate(data.split("\n")):
  35.         for j, char in enumerate(row):
  36.             if char == '#':
  37.                 elves.append(Elf(j, i))
  38.     return elves
  39.  
  40. def get_range(elves: list[Elf]):
  41.     xmin = min(elf.x for elf in elves)
  42.     xmax = max(elf.x for elf in elves)
  43.     ymin = min(elf.y for elf in elves)
  44.     ymax = max(elf.y for elf in elves)
  45.     return xmin, xmax, ymin, ymax
  46.  
  47. def print_elves(elves: list[Elf]):
  48.     xmin, xmax, ymin, ymax = get_range(elves)
  49.     grid = [['.']*(xmax-xmin+1) for _ in range(ymax - ymin + 1)]
  50.     for elf in elves:
  51.         grid[elf.y - ymin][elf.x - xmin] = '#'
  52.     for row in grid:
  53.         print(''.join(row))
  54.  
  55. def diffuse(data: str):
  56.     elves = parse(data)
  57.     round = 0
  58.     while True:
  59.         # print_elves(elves)
  60.         proposed_squares = set()
  61.         conflicts = set()
  62.         elf_set = set(map(lambda elf: (elf.x, elf.y), elves))
  63.         for elf in elves:
  64.             proposed_square = elf.find_next_square(elf_set, round)
  65.             if proposed_square is not None:
  66.                 if proposed_square in proposed_squares:
  67.                     conflicts.add(proposed_square)
  68.                 else:
  69.                     proposed_squares.add(proposed_square)
  70.         if round == 10:
  71.             xmin, xmax, ymin, ymax = get_range(elves)
  72.             print(f"Round 1: {(xmax - xmin + 1)*(ymax - ymin + 1) - len(elves)}")
  73.         round += 1
  74.         if len(proposed_squares) == 0:
  75.             break
  76.         for elf in elves:
  77.             if elf.next_square and elf.next_square not in conflicts:
  78.                 elf.move()
  79.             elf.next_square = None
  80.  
  81.     print(f"Round 2: {round}")
  82.  
  83. diffuse(input)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement