[WIP] Solution to problem 3 in Python
This commit is contained in:
parent
a453899d00
commit
ca33d9a723
138
src/Year_2019/P3.py
Normal file
138
src/Year_2019/P3.py
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
# --- Day 3: Crossed Wires ---
|
||||||
|
|
||||||
|
# The gravity assist was successful, and you're well on your way to the Venus
|
||||||
|
# refuelling station. During the rush back on Earth, the fuel management system
|
||||||
|
# wasn't completely installed, so that's next on the priority list.
|
||||||
|
|
||||||
|
# Opening the front panel reveals a jumble of wires. Specifically, two wires
|
||||||
|
# are connected to a central port and extend outward on a grid. You trace the
|
||||||
|
# path each wire takes as it leaves the central port, one wire per line of text
|
||||||
|
# (your puzzle input).
|
||||||
|
|
||||||
|
# The wires twist and turn, but the two wires occasionally cross paths. To fix
|
||||||
|
# the circuit, you need to find the intersection point closest to the central
|
||||||
|
# port. Because the wires are on a grid, use the Manhattan distance for this
|
||||||
|
# measurement. While the wires do technically cross right at the central port
|
||||||
|
# where they both start, this point does not count, nor does a wire count as
|
||||||
|
# crossing with itself.
|
||||||
|
|
||||||
|
# For example, if the first wire's path is R8,U5,L5,D3, then starting from the
|
||||||
|
# central port (o), it goes right 8, up 5, left 5, and finally down 3:
|
||||||
|
|
||||||
|
# ...........
|
||||||
|
# ...........
|
||||||
|
# ...........
|
||||||
|
# ....+----+.
|
||||||
|
# ....|....|.
|
||||||
|
# ....|....|.
|
||||||
|
# ....|....|.
|
||||||
|
# .........|.
|
||||||
|
# .o-------+.
|
||||||
|
# ...........
|
||||||
|
|
||||||
|
# Then, if the second wire's path is U7,R6,D4,L4, it goes up 7, right 6, down
|
||||||
|
# 4, and left 4:
|
||||||
|
|
||||||
|
# ...........
|
||||||
|
# .+-----+...
|
||||||
|
# .|.....|...
|
||||||
|
# .|..+--X-+.
|
||||||
|
# .|..|..|.|.
|
||||||
|
# .|.-X--+.|.
|
||||||
|
# .|..|....|.
|
||||||
|
# .|.......|.
|
||||||
|
# .o-------+.
|
||||||
|
# ...........
|
||||||
|
|
||||||
|
# These wires cross at two locations (marked X), but the lower-left one is
|
||||||
|
# closer to the central port: its distance is 3 + 3 = 6.
|
||||||
|
|
||||||
|
# Here are a few more examples:
|
||||||
|
|
||||||
|
# R75,D30,R83,U83,L12,D49,R71,U7,L72
|
||||||
|
# U62,R66,U55,R34,D71,R55,D58,R83 = distance 159
|
||||||
|
# R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51
|
||||||
|
# U98,R91,D20,R16,D67,R40,U7,R15,U6,R7 = distance 135
|
||||||
|
|
||||||
|
# What is the Manhattan distance from the central port to the closest
|
||||||
|
# intersection?
|
||||||
|
|
||||||
|
with open("files/test.txt") as f:
|
||||||
|
wire_a, wire_b = [path.split(",") for path in f.read().strip().split()]
|
||||||
|
|
||||||
|
|
||||||
|
def get_final_point(init, direction, length):
|
||||||
|
if direction == "U":
|
||||||
|
init[0] += length
|
||||||
|
elif direction == "D":
|
||||||
|
init[0] -= length
|
||||||
|
elif direction == "R":
|
||||||
|
init[1] += length
|
||||||
|
elif direction == "L":
|
||||||
|
init[1] -= length
|
||||||
|
return init
|
||||||
|
|
||||||
|
|
||||||
|
def get_path(wire):
|
||||||
|
init = [0, 0]
|
||||||
|
path = []
|
||||||
|
for step in wire:
|
||||||
|
direction, length = step[0], int(step[1:])
|
||||||
|
final_point = get_final_point(init, direction, length)
|
||||||
|
# make a copy of the final point to avoid reference to same object
|
||||||
|
path.append(final_point.copy())
|
||||||
|
init = final_point
|
||||||
|
# add starting point
|
||||||
|
return [[0, 0]] + path
|
||||||
|
|
||||||
|
|
||||||
|
# print(len(get_path(wire_a)))
|
||||||
|
# print(len(get_path(wire_b)))
|
||||||
|
|
||||||
|
|
||||||
|
def line(p1, p2):
|
||||||
|
A = p1[1] - p2[1]
|
||||||
|
B = p2[0] - p1[0]
|
||||||
|
C = p1[0] * p2[1] - p2[0] * p1[1]
|
||||||
|
return A, B, -C
|
||||||
|
|
||||||
|
|
||||||
|
def intersection(L1, L2):
|
||||||
|
D = L1[0] * L2[1] - L1[1] * L2[0]
|
||||||
|
Dx = L1[2] * L2[1] - L1[1] * L2[2]
|
||||||
|
Dy = L1[0] * L2[2] - L1[2] * L2[0]
|
||||||
|
if D != 0:
|
||||||
|
x = Dx // D
|
||||||
|
y = Dy // D
|
||||||
|
return x, y
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# L1 = line([10,1003], [476,1003])
|
||||||
|
# L2 = line([250, 500], [250, 1200])
|
||||||
|
|
||||||
|
# R = intersection(L1, L2)
|
||||||
|
# if R:
|
||||||
|
# print(f"Intersection detected at {R}")
|
||||||
|
# else:
|
||||||
|
# print("No single intersection point detected")
|
||||||
|
|
||||||
|
path_a = get_path(wire_a)
|
||||||
|
print(path_a[:5])
|
||||||
|
path_b = get_path(wire_b)
|
||||||
|
print(path_b[:5])
|
||||||
|
|
||||||
|
|
||||||
|
for p1_a, p2_a, p1_b, p2_b in zip(
|
||||||
|
path_a[:-1], path_a[1:], path_b[:-1], path_b[1:]
|
||||||
|
):
|
||||||
|
# for idx_b, (p1_b, p2_b) in enumerate(zip(path_b[:-1], path_b[1:])):
|
||||||
|
line_a = line(p2_a, p1_a)
|
||||||
|
print(line_a)
|
||||||
|
line_b = line(p2_b, p1_b)
|
||||||
|
print(line_b)
|
||||||
|
R = intersection(line_a, line_b)
|
||||||
|
if R:
|
||||||
|
print(p1_a, p2_a, p1_b, p2_b)
|
||||||
|
break
|
Loading…
Reference in New Issue
Block a user