◂ 24 décembre 2023 ▸
Never Tell Me The Odds : Trouver des intersections de droites paramétriques, puis résolution d'équations non linéaires
233210433951170, 272655040388795, 179982504986147 @ 39, -98, 166
385274025881243, 351578921558552, 375160114124378 @ -71, -36, -9
298962016918939, 322446494312107, 293073189215975 @ 36, 8, 96
⋮
Autre possibilité que de résoudre des équations compliquées en recommençant tant qu'on n'a pas les bonnes équations: trouver une paire de directions parallèles, ce qui donne un plan avec lequel intersecter les autres trajectoires.
- code1.py
- code2.py
- code2_paralleles.py
import re, itertools
FICHIER_TEST = False
if FICHIER_TEST:
BORD_INF = 7
BORD_SUP = 27
file = 'input2.txt'
else:
BORD_INF = 200_000_000_000_000
BORD_SUP = 400_000_000_000_000
file = 'input.txt'
f = open(file, 'r', encoding='utf-8')
lines = [line[:-1] for line in f.readlines()]
def parse_ints(line: str) -> list[int]:
return [ int(token) for token in re.split('[^-0-9]+', line) if token ]
Vecteur = tuple[int,int,int]
Position = tuple[int,int,int]
pos: list[Position] = []
vit: list[Vecteur] = []
for line in lines:
values = parse_ints(line)
pos.append(tuple(values[:3]))
vit.append(tuple(values[3:]))
nb = 0
for i,j in itertools.combinations(range(len(pos)), 2):
x1, y1, _, x2, y2,_ = *pos[i], *pos[j]
vx1,vy1,_,vx2,vy2,_ = *vit[i], *vit[j]
# matrice pour résolution pos1 + t1 * vit1 = pos2 + t2 * vit2
a,b,c,d = vx1, -vx2, vy1, -vy2
det = a*d - b*c
if det == 0:
continue # Si parallèle, même si trajectoire confondues et dans le bon sens, on ne compte pas.
t1 = d*(x2-x1) + -b*(y2-y1) # vaut le vrai t1 multiplié par det
t2 = -c*(x2-x1) + a*(y2-y1) # idem
if det < 0:
t1, t2, det = -t1, -t2, -det
if (t1 < 0 or t2 < 0): # on va dans le futur
if FICHIER_TEST:
if t1 < 0:
print(f"Grêlons {i+1,j+1}: 1er dans le passé")
if t2 < 0:
print(f"Grêlons {i+1,j+1}: 2e dans le passé")
continue
else:
assert not (t1 == 0 or t2 == 0), "Grêlons stationnaires ou verticaux non prévus."
x = x1 * det + vx1 * t1 # x est la valeur de la pos multipliée par det (qui a été absolufié)
y = y1 * det + vy1 * t1 # idem
assert not (x==BORD_INF*det or y==BORD_INF*det or x==BORD_SUP*det or y==BORD_SUP*det), "Cas limites non prévus."
if (BORD_INF*det <= x <= BORD_SUP*det) and (BORD_INF*det <= y <= BORD_SUP*det):
nb += 1
print("Réponse partie 1:", nb)