from lib import * EXAMPLE = """....#.. ..###.# #...#.# .#...## #.###.. ##.#.## .#..#.. """ # EXAMPLE = """..... # ..##. # ..#.. # ..... # ..##. # ..... # """ N = (-1, 0) NE = (-1, 1) E = (0, 1) SE = (1, 1) S = (1, 0) SW = (1, -1) W = (0, -1) NW = (-1, -1) adj8 = [ N, NE, E, SE, S, SW, W, NW, ] def print_field(elves): rmin, rmax = min(map(fst, elves)), max(map(fst, elves)) cmin, cmax = min(map(snd, elves)), max(map(snd, elves)) count = 0 for row in range(rmin, rmax + 1): rs = "" for col in range(cmin, cmax + 1): if (row, col) in elves: rs += "#" else: rs += "." count += 1 print(rs) print() return count def solve(input: Input, second=False): dirs_to_check = [ (N, NE, NW), (S, SE, SW), (W, NW, SW), (E, NE, SE), ] round = 0 elves = input.grid2().find('#') while True: # print_field(elves) nes = set() proposed_fields = {} for e in list(elves): for o in adj8: adj = (e[0] + o[0], e[1] + o[1]) if adj in elves: break else: nes.add(e) continue proposed_field = None for dirs in dirs_to_check: for o in dirs: adj = (e[0] + o[0], e[1] + o[1]) if adj in elves: break else: o = dirs[0] proposed_field = (e[0] + o[0], e[1] + o[1]) break if proposed_field is None: nes.add(e) elif proposed_field in proposed_fields: proposed_fields[proposed_field].append(e) else: proposed_fields[proposed_field] = [e] for ne, olves in proposed_fields.items(): if len(olves) == 1: nes.add(ne) else: for e in olves: nes.add(e) dirs_to_check = dirs_to_check[1:] + dirs_to_check[:1] round += 1 if second and elves == nes: return round elif not second and round == 10: return print_field(nes) elves = nes def main(): DAY_INPUT = "i23.txt" print("Example 1:", solve(Input(EXAMPLE))) print("Solution 1:", solve(Input(DAY_INPUT))) print("Example 2:", solve(Input(EXAMPLE), True)) print("Solution 2:", solve(Input(DAY_INPUT), True)) if __name__ == "__main__": main()