My Advent of Code solutions in Python. kevinyap.ca/2019/12/going-fast-in-advent-of-code/
advent-of-code python
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 63 lines 2.0 kB view raw
1import fileinput 2from collections import defaultdict 3 4from utils import Point, N, NE, E, SE, S, SW, W, NW, min_max_xy 5 6 7BOARD = {} 8 9for y, line in enumerate(fileinput.input()): 10 for x, c in enumerate(line.strip()): 11 BOARD[Point(x, y)] = c 12 13# N and S are switched from the problem statement because of 14# the convention of using +y -> N in my utils, which does have 15# an effect on the interaction between elves in this problem. 16CHECKS = [ 17 [[S, SE, SW], S], 18 [[N, NE, NW], N], 19 [[W, NW, SW], W], 20 [[E, NE, SE], E], 21] 22 23for i in range(100000): 24 proposal = defaultdict(list) 25 for p, c in BOARD.items(): 26 if c == '#': 27 # If elf has no neighbours in all 8 directions, don't consider moving. 28 if not any(BOARD.get(n) == '#' for n in p.neighbours_8()): 29 continue 30 31 # Add elf's proposed location to `proposal`. 32 for d in range(4): 33 checks, move = CHECKS[(i + d) % 4] 34 if any(BOARD.get(p + c, ' ') == '#' for c in checks): 35 continue 36 37 proposal[p + move].append(p) 38 break 39 40 for new_loc in proposal: 41 elves = proposal[new_loc] 42 # If only one elf wants to move there, they can move (and vacate their old spot). 43 if len(elves) == 1: 44 BOARD[elves[0]] = '.' 45 BOARD[new_loc] = '#' 46 47 # Answer to part 1, compute number of empty squares within the bounds. 48 if i == 9: 49 elves = [p for p in BOARD if BOARD[p] == '#'] 50 min_x, max_x, min_y, max_y = min_max_xy(elves) 51 blanks = 0 52 for y in range(min_y, max_y + 1): 53 for x in range(min_x, max_x + 1): 54 p = Point(x, y) 55 if BOARD.get(p) != '#': 56 blanks += 1 57 58 print("Part 1:", blanks) 59 60 # Empty proposal list -> no elves moved, the answer to part 2. 61 if len(proposal) == 0: 62 print("Part 2:", i + 1) 63 break