# Advent of Code Day 3¶

In :
with open("AoC/input3.txt") as input_file:

In :
def segments(steps):
segments = []
current = (0, 0)
for step in steps:
if step == 'R':
b = (current + step, current)
elif step == 'U':
b = (current, current + step)
elif step == 'L':
b = (current - step, current)
elif step == 'D':
b = (current, current - step)
segments.append((current, b))
current = b
return segments

In :
def intersect(segmentA, segmentB):
a1, a2 = segmentA
b1, b2 = segmentB

for ax0, ax1 in [(0, 1), (1, 0)]:
if a1[ax0] == a2[ax0] and b1[ax1] == b2[ax1] and \
min(a1[ax1], a2[ax1]) <= b1[ax1] and b1[ax1] <= max(a1[ax1], a2[ax1]) and \
min(b1[ax0], b2[ax0]) <= a1[ax0] and a1[ax0] <= max(b1[ax0], b2[ax0]):
return a1[ax0], b1[ax1]

# Doesn't handle overlaps
return None

In :
def process(input_str):
parsed = [[(y, int(y[1:])) for y in x.split(",")] for x in input_str.strip().split("\n")]
lines = list(map(segments, parsed))

min_dist = None
for lineA in lines:
for lineB in lines:
pt = intersect(lineA, lineB)
dist = abs(pt) + abs(pt) if pt else None
if dist and (not min_dist or min_dist > dist):
min_dist = dist

return min_dist

In :
process(test_input)

Out:
221
In :
process("""R75,D30,R83,U83,L12,D49,R71,U7,L72
U62,R66,U55,R34,D71,R55,D58,R83""")

Out:
159
In :
def length(line):
return abs(line - line) + abs(line - line)

In :
def process2(input_str):
parsed = [[(y, int(y[1:])) for y in x.split(",")] for x in input_str.strip().split("\n")]
lines = list(map(segments, parsed))

min_steps = None
stepsA = 0
for lineA in lines:

stepsB = 0
for lineB in lines:
pt = intersect(lineA, lineB)
steps = stepsA + stepsB + length((lineA, pt)) + length((lineB, pt)) if pt else None
if steps and (not min_steps or min_steps > steps) and not (pt == 0 and pt == 0):
print(pt, steps, lineA, lineB)
min_steps = steps

stepsB += length(lineB)

stepsA += length(lineA)

return min_steps

In :
process2("""R75,D30,R83,U83,L12,D49,R71,U7,L72
U62,R66,U55,R34,D71,R55,D58,R83""")

(158, -12) 610 ((158, -30), (158, 53)) ((155, -12), (238, -12))

Out:
610
In :
process2(test_input)

(998, 349) 39290 ((998, 0), (998, 367)) ((584, 349), (1238, 349))
(367, 1211) 25888 ((998, 367), (1733, 367)) ((1211, 823), (1211, -117))
(1733, 823) 23850 ((1733, 367), (1733, 1293)) ((2184, 823), (1211, 823))
(1756, 1665) 18542 ((1756, 1293), (1756, 1750)) ((1330, 1665), (1968, 1665))

Out:
18542

I started this one early in the morning and not at midnight, but timed myself just to see how I perform. I ended up taking 50 minutes, which is pretty slow because of several easy mistakes. Notes to self:

• Remember to structure the code to allow easily testing sample inputs.
• Actually remember to test sample inputs.
• It might be more valuable to edit the solution in place for the second star instead of starting from scratch.
• Keep my notebook ready to paste strings of test inputs easily

Looking at the winning solutions from the subreddit, I ended up wasting too much time doing intersections instead of simply brute forcing a solution by assembling a collection of grid points -- which is a good trick to remember for grid/integer based problems.

TODO: Try drawing graphs of wires someday.