advent2023/xmaseve.py

47 lines
1.7 KiB
Python
Executable File

#!/usr/bin/env python3
from useful import *
from fractions import Fraction
debug = False
if len(sys.argv) >= 2 and sys.argv[1] == '-v':
debug = True
sys.argv = sys.argv[:1] + sys.argv[2:]
def makelin(l):
px, py, _, vx, vy, _ = numbers(l)
a = Fraction(vy, vx)
b = py - px * a
return a, b, px, vx > 0
lins = [makelin(l) for l in lines(open(0))]
bot = 200000000000000 if len(sys.argv) < 2 else int(sys.argv[1])
top = 400000000000000 if len(sys.argv) < 3 else int(sys.argv[2])
total = 0
for (a1, b1, px1, vx1_is_pos), (a2, b2, px2, vx2_is_pos) in combinations(lins, 2):
if debug:
print('Hailstone A: Moving from %s in a %s direction' % (
px1, 'positive' if vx1_is_pos else 'negative'), file=sys.stderr)
print('Hailstone B: %sx + %s = %sx + %s ?' % (a1, b1, a2, b2), file=sys.stderr)
if a1 == a2:
if debug:
print('Hailstones\' paths are parallel; they never intersect.\n', file=sys.stderr)
else:
ad, bd = (a1 - a2), (b2 - b1)
x = bd / ad
y = a1 * x + b1
y_sanity = a2 * x + b2
assert y == y_sanity
if bot <= x <= top and bot <= y <= top:
if (x < px1) != vx1_is_pos and (x < px2) != vx2_is_pos: # "xor"
if debug:
print('Hailstones\' paths will intersect (at x=%s, y=%s).\n' % (x, y), file=sys.stderr)
total += 1
else:
if debug:
print('Hailstones\' paths intersected in the past (at x=%s, y=%s).\n' % (x, y), file=sys.stderr)
else:
if debug:
print('Hailstones\' paths cross sometime (at x=%s, y=%s).\n' % (x, y), file=sys.stderr)
print(total)