Created
December 24, 2023 06:51
-
-
Save jackpal/368466f268cbc85217019974857d9efb to your computer and use it in GitHub Desktop.
Advent of Code 2023 Day 24 Solution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Parse input | |
def parse_input(s): | |
out = [] | |
for line in s.strip().split('\n'): | |
p,v = line.split(' @ ') | |
pp = [int(i) for i in p.split(',')] | |
vv = [int(i) for i in v.split(',')] | |
out.append((pp,vv)) | |
return out | |
# Part 1 Nothing special | |
def solve_part_1(input): | |
if len(input) < 10: | |
min_coord = 7 | |
max_coord = 27 | |
else: | |
min_coord = 200000000000000 | |
max_coord = 400000000000000 | |
def sign(a): | |
if a < 0: | |
return -1 | |
elif a == 0: | |
return 0 | |
else: | |
return 1 | |
def line_intersection(line1, line2): | |
"""https://stackoverflow.com/questions/20677795/how-do-i-compute-the-intersection-point-of-two-lines""" | |
xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0]) | |
ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1]) | |
def det(a, b): | |
return a[0] * b[1] - a[1] * b[0] | |
div = det(xdiff, ydiff) | |
if div == 0: | |
return None | |
d = (det(*line1), det(*line2)) | |
x = det(d, xdiff) / div | |
y = det(d, ydiff) / div | |
return x, y | |
def hail_to_line(h): | |
p,v = h | |
p1 = (p[0], p[1]) | |
p2 = (p[0] + v[0], p[1] + v[1]) | |
pt = [p1, p2] | |
return pt | |
def hail_intersection(a,b): | |
sect = line_intersection(hail_to_line(a), hail_to_line(b)) | |
if sect != None: | |
def crossed_future(sect, a): | |
sx,sy = sect | |
return sign(sx - a[0][0]) == sign(a[1][0]) and sign(sy - a[0][1]) == sign(a[1][1]) | |
if crossed_future(sect, a) and crossed_future(sect, b): | |
return sect | |
return None | |
cross_count = 0 | |
for i, a in enumerate(input): | |
for j, b in enumerate(input): | |
if i == j: | |
break | |
sect =hail_intersection(a,b) | |
print(f'{a} {b} = {sect}') | |
if sect != None and min_coord <= sect[0] <= max_coord and min_coord <= sect[1] <= max_coord: | |
print("Crossed") | |
cross_count += 1 | |
print(cross_count) | |
return cross_count | |
def solve_part_2(input): | |
"""Print out a set of instructions to the Open-Source "SageMath" program to solve the linear equations.""" | |
eqn = [] | |
fn = [] | |
t = [] | |
eqn.append('var(\'xg yg zg dxg dyg dzg\')') | |
for i,line in enumerate(input[:10]): | |
eqn.append(f'var(\'t{i}\')') | |
t.append(f't{i}') | |
for d in range(3): | |
c = "xyz"[d] | |
eqn.append(f'f{i}{d} = {c}g+d{c}g*t{i} == {line[0][d]} + {line[1][d]}*t{i}') | |
fn.append(f'f{i}{d}') | |
fns = ','.join(fn) | |
ts = ','.join(t) | |
eqn.append(f'solve([{fns}], [xg,yg,zg,dxg,dyg,dzg,{ts}])') | |
print('\n'.join(eqn)) | |
return None |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment