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 2023/19

+109
+109
2023/day19.py
··· 1 + import copy 2 + import fileinput 3 + from utils import mul 4 + 5 + 6 + # Parse problem input. 7 + RULES = {} 8 + WORKFLOWS = [] 9 + for line in fileinput.input(): 10 + line = line.strip() 11 + 12 + if line.startswith('{'): 13 + WORKFLOWS.append([x for x in line[1:-1].split(',')]) 14 + elif line.endswith('}'): 15 + name, rest = line.split('{') 16 + rules = [] 17 + for r in rest[:-1].split(','): 18 + if all(x.isalpha() for x in r): 19 + rules.append(r) 20 + else: 21 + a, b, cond = r[0], r[1], r[2:] 22 + cond, out = cond.split(':') 23 + rules.append((a, b, int(cond), out)) 24 + 25 + RULES[name] = rules 26 + 27 + # Solve part 1. 28 + part_1 = 0 29 + for wf in WORKFLOWS: 30 + regs = {} 31 + for state in wf: 32 + reg, val = state.split('=') 33 + regs[reg] = int(val) 34 + 35 + curr = 'in' 36 + while curr not in ('A', 'R'): 37 + for rule in RULES[curr]: 38 + if type(rule) == str: 39 + curr = rule 40 + break 41 + 42 + reg, cond, val, next_rule = rule 43 + if cond == '<': 44 + if regs[reg] < val: 45 + curr = next_rule 46 + break 47 + elif cond == '>': 48 + if regs[reg] > val: 49 + curr = next_rule 50 + break 51 + 52 + if curr == 'A': 53 + part_1 += sum(regs.values()) 54 + 55 + print("Part 1:", part_1) 56 + 57 + 58 + # Solve part 2. 59 + INITIAL_HYPERCUBE = {k: [1, 4000] for k in 'xmas'} 60 + horizon = [('in', INITIAL_HYPERCUBE)] 61 + 62 + ACCEPTED = [] 63 + 64 + while horizon: 65 + curr, intervals = horizon.pop() 66 + 67 + if curr == 'A': 68 + ACCEPTED.append(intervals) 69 + continue 70 + elif curr == 'R': 71 + continue 72 + 73 + for rule in RULES[curr]: 74 + if type(rule) == str: 75 + horizon.append((rule, intervals)) 76 + break 77 + 78 + reg, cond, val, next_rule = rule 79 + if cond == '<': 80 + if intervals[reg][0] >= val: 81 + continue 82 + 83 + curr_bound = intervals[reg][1] 84 + new_intervals = copy.deepcopy(intervals) 85 + new_intervals[reg][1] = min(val - 1, curr_bound) 86 + horizon.append((next_rule, copy.deepcopy(new_intervals))) 87 + 88 + # Propagate the inverse state to the next case in the rule. 89 + curr_bound = intervals[reg][0] 90 + inverse_intervals = copy.deepcopy(intervals) 91 + inverse_intervals[reg][0] = max(val, curr_bound) 92 + intervals = inverse_intervals 93 + 94 + elif cond == '>': 95 + if intervals[reg][1] <= val: 96 + continue 97 + 98 + curr_bound = intervals[reg][0] 99 + new_intervals = copy.deepcopy(intervals) 100 + new_intervals[reg][0] = max(val + 1, curr_bound) 101 + horizon.append((next_rule, copy.deepcopy(new_intervals))) 102 + 103 + # Propagate the inverse state to the next case in the rule. 104 + curr_bound = intervals[reg][1] 105 + inverse_intervals = copy.deepcopy(intervals) 106 + inverse_intervals[reg][1] = min(val, curr_bound) 107 + intervals = inverse_intervals 108 + 109 + print("Part 2:", sum(mul(b - a + 1 for a, b in interval.values()) for interval in ACCEPTED))