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/24

+87
+87
2023/day24.py
··· 1 + import fileinput 2 + from itertools import combinations 3 + 4 + from utils import parse_nums 5 + 6 + 7 + def find_intersection(x1, y1, x2, y2, x3, y3, x4, y4): 8 + # https://stackoverflow.com/a/51127674 9 + px = ((x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4)) / ((x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)) 10 + py = ((x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4)) / ((x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)) 11 + return [px, py] 12 + 13 + # Parse problem input. 14 + HAILSTONES = [tuple(parse_nums(line)) for line in fileinput.input()] 15 + 16 + MIN = 200000000000000 17 + MAX = 400000000000000 18 + 19 + part_1 = 0 20 + 21 + for a, b in combinations(HAILSTONES, 2): 22 + ax, ay, _, avx, avy, _ = a 23 + bx, by, _, bvx, bvy, _ = b 24 + 25 + a_slope = avy / avx 26 + a_b = ay - (a_slope * ax) 27 + 28 + a_start = a_slope * MIN + a_b 29 + a_end = a_slope * MAX + a_b 30 + 31 + b_slope = bvy / bvx 32 + b_b = by - (b_slope * bx) 33 + 34 + b_start = b_slope * MIN + b_b 35 + b_end = b_slope * MAX + b_b 36 + 37 + try: 38 + px, py = find_intersection(MIN, a_start, MAX, a_end, MIN, b_start, MAX, b_end) 39 + except: 40 + # Parallel lines. 41 + continue 42 + 43 + # Intersection in A's past 44 + if avx > 0 and px < ax: 45 + continue 46 + elif avx < 0 and px > ax: 47 + continue 48 + 49 + # Intersection in B's past 50 + if bvx > 0 and px < bx: 51 + continue 52 + elif bvx < 0 and px > bx: 53 + continue 54 + 55 + # Good intersection in zone. 56 + if MIN <= px <= MAX and MIN <= py <= MAX: 57 + part_1 += 1 58 + 59 + print("Part 1:", part_1) 60 + 61 + # Solve Part 2. 62 + try: 63 + from z3 import Real, Solver 64 + except: 65 + print("Part 2 requires z3 to be installed (`pip install z3-solver`)") 66 + import sys 67 + sys.exit() 68 + 69 + mx = Real('mx') 70 + my = Real('my') 71 + mz = Real('mz') 72 + mxv = Real('mxv') 73 + myv = Real('myv') 74 + mzv = Real('mzv') 75 + c = [Real('c' + str(n)) for n in range(len(HAILSTONES))] 76 + 77 + s = Solver() 78 + 79 + for i, (px, py, pz, vx, vy, vz) in enumerate(HAILSTONES): 80 + s.add(c[i] >= 0) 81 + s.add(mx + c[i] * mxv == px + c[i] * vx) 82 + s.add(my + c[i] * myv == py + c[i] * vy) 83 + s.add(mz + c[i] * mzv == pz + c[i] * vz) 84 + 85 + s.check() 86 + m = s.model() 87 + print("Part 2:", m[mx].as_long() + m[my].as_long() + m[mz].as_long())