Skip to content

Commit e92442e

Browse files
committed
feat: 2023 day 24
1 parent 905e2e6 commit e92442e

File tree

6 files changed

+383
-64
lines changed

6 files changed

+383
-64
lines changed

2023/24.txt

Lines changed: 300 additions & 0 deletions
Large diffs are not rendered by default.

2023/24_expa.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2

2023/24_expb.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
47

2023/24_test.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
19, 13, 30 @ -2, 1, -2
2+
18, 19, 22 @ -1, -1, -2
3+
20, 25, 34 @ -2, -2, -4
4+
12, 31, 28 @ -1, -2, -1
5+
20, 19, 15 @ 1, -5, -3

2023/24a.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from aoc import *
2+
from itertools import combinations
3+
from sympy import *
4+
from sympy.geometry import *
5+
6+
7+
def main(input_file: str):
8+
inp = lines(input_file)
9+
points = []
10+
for l in inp:
11+
left, right = l.split(' @ ')
12+
left = tuple(int(x) for x in left.split(', '))
13+
right = tuple(int(x) for x in right.split(', '))
14+
points.append((left, right))
15+
16+
x_min = 200000000000000
17+
x_max = 400000000000000
18+
19+
# For test input
20+
# x_min = 7
21+
# x_max = 27
22+
23+
suma = 0
24+
for ((x, y, z), (a, b, c)), ((i, j, k), (d, e, f)) in combinations(points, 2):
25+
q = Point(x, y)
26+
w = Point(x + a, y + b)
27+
l1 = Line(q, w)
28+
l1 = Ray(q, w)
29+
r = Point(i, j)
30+
t = Point(i + d, j + e)
31+
l2 = Line(r, t)
32+
l2 = Ray(r, t)
33+
inter = intersection(l1, l2)
34+
if inter:
35+
if x_min <= inter[0][0] <= x_max and x_min <= inter[0][1] <= x_max:
36+
suma += 1
37+
return suma
38+
39+
DAY = 24
40+
FILE_TEST = f"{DAY}_test.txt"
41+
FILE_EXP = f"{DAY}_expa.txt"
42+
FILE = f"{DAY}.txt"
43+
# test_and_submit(main, FILE_TEST, FILE_EXP, FILE, DAY)
44+
# print(main(FILE_TEST))
45+
print(main(FILE))

2023/24b.py

Lines changed: 31 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,48 @@
11
from aoc import *
2-
from statistics import median, mode
3-
from more_itertools import windowed, take, peekable, chunked, first_true, split_when, first_true
4-
from heapq import *
5-
# from functools import reduce, cache, cmp_to_key
6-
from functools import cache
7-
from math import ceil
8-
import re
9-
from blessed import BlessedList
10-
from copy import deepcopy
11-
import operator
12-
from string import ascii_letters, ascii_lowercase, ascii_uppercase, digits, hexdigits, whitespace
13-
from pprint import pprint as pp
14-
import bisect
15-
import math
16-
from itertools import pairwise, combinations
17-
import sys
18-
from collections import defaultdict, OrderedDict, deque, Counter
19-
# from ordered_set import OrderedSet
20-
from sympy import *
21-
from sympy.geometry import *
2+
from sympy import symbols
3+
from sympy.solvers.polysys import solve_poly_system
224

235

6+
# Geometrical representation: H is a set of lines (more precisely rays, but this
7+
# doesn't matter in this task) that represent the trajectories of hailstones. We
8+
# have to find line l (trajectory of our stone) that intersects all lines in H.
9+
#
10+
# This can be represented analytically as a system of equations (they aren't
11+
# linear as there is a multiplication of two unknowns).
12+
#
13+
# As line is defined by two points, if we find a unique line that intersects
14+
# three lines from H, it should also intersect all other lines (considering the
15+
# input is correct).
16+
#
17+
# Many people on r/adventofcode used Z3. I wanted to use a Python solution and
18+
# since I used sympy for part one, this post was a good inspiration for me:
19+
# https://www.reddit.com/r/adventofcode/comments/18pnycy/comment/kepmry2/?utm_source=share&utm_medium=web2x&context=3
2420
def main(input_file: str):
2521
inp = lines(input_file)
2622
points = []
27-
for l in inp:
23+
system = []
24+
x, y, z, vx, vy, vz = symbols('x y z vx vy vz')
25+
ts = []
26+
# Three lines (points) is enough. It will define the throw line for all
27+
# other hailstones.
28+
for i, l in enumerate(inp[:3]):
2829
left, right = l.split(' @ ')
29-
left = tuple(int(x) for x in left.split(', '))
30-
right = tuple(int(x) for x in right.split(', '))
30+
left = tuple(int(j) for j in left.split(', '))
31+
right = tuple(int(j) for j in right.split(', '))
3132
points.append((left, right))
33+
t = symbols(f't{i}')
34+
ts.append(t)
35+
system.append(x + vx * t - left[0] - right[0] * t)
36+
system.append(y + vy * t - left[1] - right[1] * t)
37+
system.append(z + vz * t - left[2] - right[2] * t)
3238

33-
x_min = 200000000000000
34-
x_max = 400000000000000
35-
# x_min = 7
36-
# x_max = 27
37-
suma = 0
38-
time = []
39-
for i in range(1, 4):
40-
new_points = []
41-
for (x, y, z), (a, b, c) in points:
42-
new_points.append((x+a*i, y+b*i, z+c*i))
43-
time.append(new_points)
44-
for i1, p1 in enumerate(time[0]):
45-
for i2, p2 in enumerate(time[1]):
46-
if i2 == i1:
47-
continue
48-
for i3, p3 in enumerate(time[2]):
49-
if i3 in [i1, i2]:
50-
continue
51-
q = Point(p1)
52-
w = Point(p2)
53-
line = Line(q, w)
54-
if line.intersection(Point(p3)):
55-
print(p1, p2, p3)
39+
return sum(solve_poly_system(system, x, y, z, vx, vy, vz, *ts)[0][:3])
5640

57-
# for ((x, y, z), (a, b, c)), ((i, j, k), (d, e, f)) in combinations(points, 2):
58-
# q = Point(x, y)
59-
# w = Point(x + a, y + b)
60-
# # w = Point(a, b)
61-
# l1 = Line(q, w)
62-
# l1 = Ray(q, w)
63-
# r = Point(i, j)
64-
# t = Point(i + d, j + e)
65-
# # t = Point(d, e)
66-
# l2 = Line(r, t)
67-
# l2 = Ray(r, t)
68-
# inter = intersection(l1, l2)
69-
# if inter:
70-
# if x_min <= inter[0][0] <= x_max and x_min <= inter[0][1] <= x_max:
71-
# suma += 1
72-
# # print(f'{((x, y, z), (a, b, c)), ((i, j, k), (d, e, f))}: will cross at {inter}')
73-
return
7441

7542
DAY = 24
7643
FILE_TEST = f"{DAY}_test.txt"
7744
FILE_EXP = f"{DAY}_expa.txt"
7845
FILE = f"{DAY}.txt"
7946
# test_and_submit(main, FILE_TEST, FILE_EXP, FILE, DAY)
80-
# print(main(FILE_TEST))
47+
print(main(FILE_TEST))
8148
print(main(FILE))

0 commit comments

Comments
 (0)