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.

Add solution for 2018/22

+101
+97
2018/day22.py
··· 1 + import os # NOQA 2 + import sys # NOQA 3 + import heapq 4 + import fileinput 5 + from collections import Counter, defaultdict, deque, namedtuple # NOQA 6 + 7 + from utils import memoize 8 + from utils import Point, DIRS, DIRS_4, DIRS_8 # NOQA 9 + 10 + 11 + MOD = 20183 12 + 13 + 14 + @memoize 15 + def geo_index(x, y): 16 + if x == 0 and y == 0: 17 + return 0 18 + elif x == TX and y == TY: 19 + return 0 20 + elif y == 0: 21 + return (x * 16807) % MOD 22 + elif x == 0: 23 + return (y * 48271) % MOD 24 + else: 25 + return (ero_level(x - 1, y) * ero_level(x, y - 1)) % MOD 26 + 27 + 28 + @memoize 29 + def ero_level(x, y): 30 + return (geo_index(x, y) + DEPTH) % MOD 31 + 32 + 33 + @memoize 34 + def risk_level(x, y): 35 + return ero_level(x, y) % 3 36 + 37 + 38 + lines = fileinput.input() 39 + DEPTH = int(lines[0].split()[1]) 40 + TX, TY = (int(x) for x in lines[1].split()[1].split(',')) 41 + 42 + print "Total risk level for rectangle:", sum(risk_level(x, y) for x in range(TX + 1) for y in range(TY + 1)) 43 + 44 + 45 + # In rocky regions (0), can use torch (1) or gear (2) 46 + # In wet regions (1), can use gear (2) or neither (0) 47 + # In narrow regions (2), can use neither (0) or torch (1) 48 + # 49 + # Start at (0, 0) with the torch equipped. 50 + ROCKY = 0 51 + WET = 1 52 + NARROW = 2 53 + 54 + NEITHER = 0 55 + TORCH = 1 56 + GEAR = 2 57 + 58 + items = [NEITHER, TORCH, GEAR] 59 + 60 + allowed = { 61 + ROCKY: [TORCH, GEAR], 62 + WET: [GEAR, NEITHER], 63 + NARROW: [NEITHER, TORCH], 64 + } 65 + 66 + State = namedtuple('State', 'time x y item') 67 + 68 + state = State(0, 0, 0, TORCH) 69 + horizon = [state] 70 + seen = {} 71 + 72 + while horizon: 73 + time, x, y, item = heapq.heappop(horizon) 74 + 75 + if x == TX and y == TY and item == TORCH: 76 + print "Minutes to reach the target:", time 77 + break 78 + 79 + # Hand-wavy upper bound on horizontal search limit (technically should be TX + TY) 80 + if x > TX * 3: 81 + continue 82 + 83 + if seen.get((x, y, item), 1e10) <= time: 84 + continue 85 + 86 + next_entry = (time, x, y, item) 87 + 88 + seen[(x, y, item)] = min(seen.get((x, y, item), 1e10), time) 89 + region = risk_level(x, y) 90 + 91 + for next_item in items: 92 + if next_item in allowed[risk_level(x, y)] and next_item != item: 93 + heapq.heappush(horizon, State(time + 7, x, y, next_item)) 94 + 95 + for n in Point(x, y).neighbours_4(): 96 + if n.x >= 0 and n.y >= 0 and risk_level(n.x, n.y) != item: 97 + heapq.heappush(horizon, State(time + 1, n.x, n.y, item))
+2
2018/inputs/22.txt
··· 1 + depth: 11817 2 + target: 9,751
+2
2018/outputs/22.txt
··· 1 + 7402 2 + 1025