Day 3 part 2
This commit is contained in:
parent
aeaec72182
commit
8ca85d8ea5
76
2019/day3.py
76
2019/day3.py
|
@ -1,9 +1,12 @@
|
||||||
|
from collections import defaultdict
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
EX0 = ["R8,U5,L5,D3", "U7,R6,D4,L4"]
|
EX0 = ["R8,U5,L5,D3", "U7,R6,D4,L4"]
|
||||||
EX1 = ["R75,D30,R83,U83,L12,D49,R71,U7,L72", "U62,R66,U55,R34,D71,R55,D58,R83"]
|
EX1 = ["R75,D30,R83,U83,L12,D49,R71,U7,L72", "U62,R66,U55,R34,D71,R55,D58,R83"]
|
||||||
EX2 = ["R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51", "U98,R91,D20,R16,D67,R40,U7,R15,U6,R7"]
|
EX2 = ["R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51", "U98,R91,D20,R16,D67,R40,U7,R15,U6,R7"]
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
with open("day3.txt", "rt") as input_file:
|
with open("day3.txt", "rt") as input_file:
|
||||||
lines = list(input_file.readlines())
|
lines = list(input_file.readlines())
|
||||||
|
@ -12,64 +15,61 @@ def main():
|
||||||
def solve(input_lines):
|
def solve(input_lines):
|
||||||
wires = [(wire_id, line.strip().split(",")) for wire_id, line in enumerate(input_lines)]
|
wires = [(wire_id, line.strip().split(",")) for wire_id, line in enumerate(input_lines)]
|
||||||
grid = compute_grid(wires)
|
grid = compute_grid(wires)
|
||||||
intersections = get_intersections(grid)
|
|
||||||
# print("Intersections:", intersections)
|
# Part 1
|
||||||
distances = get_manhattan_distances(intersections)
|
intersections = [(x, y) for x, l in grid.items() for y, wl in l.items() if len(wl) > 1]
|
||||||
# print("Distances:", distances)
|
print("Intersections:", intersections)
|
||||||
print("Min:", min(distances))
|
distances = [abs(p[0]) + abs(p[1]) for p in intersections]
|
||||||
|
print("Distances:", distances)
|
||||||
|
print("Min distance:", min(distances))
|
||||||
|
|
||||||
|
# Part 2
|
||||||
|
min_steps = get_earliest_intersections(grid)
|
||||||
|
print(f"Min steps found: {min_steps}.")
|
||||||
|
|
||||||
def compute_grid(wires):
|
def compute_grid(wires):
|
||||||
grid = {}
|
grid = defaultdict(lambda: defaultdict(list))
|
||||||
for wire_id, codes in wires:
|
for wire_id, codes in wires:
|
||||||
fill_grid(wire_id, codes, grid)
|
fill_grid(wire_id, codes, grid)
|
||||||
return grid
|
return grid
|
||||||
|
|
||||||
CODE_RE = re.compile(r"(\w)(\d+)")
|
CODE_RE = re.compile(r"(\w)(\d+)")
|
||||||
|
|
||||||
|
MOVES = {
|
||||||
|
"R": (0, +1),
|
||||||
|
"L": (0, -1),
|
||||||
|
"U": (+1, 0),
|
||||||
|
"D": (-1, 0),
|
||||||
|
}
|
||||||
|
|
||||||
def fill_grid(wire_id, codes, grid):
|
def fill_grid(wire_id, codes, grid):
|
||||||
x = 0
|
x = 0
|
||||||
y = 0
|
y = 0
|
||||||
|
steps = 0
|
||||||
for code in codes:
|
for code in codes:
|
||||||
match = CODE_RE.match(code)
|
match = CODE_RE.match(code)
|
||||||
op, arg = match.groups()
|
op, arg = match.groups()
|
||||||
for _ in range(int(arg)):
|
for _ in range(int(arg)):
|
||||||
if op == "R":
|
move = MOVES[op]
|
||||||
y += 1
|
x, y = x + move[0], y + move[1]
|
||||||
elif op == "L":
|
steps += 1
|
||||||
y -= 1
|
inc_point((x, y), grid, wire_id, steps)
|
||||||
elif op == "U":
|
|
||||||
x += 1
|
|
||||||
elif op == "D":
|
|
||||||
x -= 1
|
|
||||||
inc_point((x, y), grid, wire_id)
|
|
||||||
|
|
||||||
def inc_point(point, grid, wire_id):
|
def inc_point(point, grid, wire_id, steps):
|
||||||
x, y = point
|
x, y = point
|
||||||
if x not in grid:
|
if wire_id not in [wid for wid, s in grid[x][y]]:
|
||||||
grid[x] = {}
|
grid[x][y].append((wire_id, steps))
|
||||||
if y not in grid[x]:
|
|
||||||
grid[x][y] = [wire_id]
|
|
||||||
elif wire_id not in grid[x][y]:
|
|
||||||
grid[x][y].append(wire_id)
|
|
||||||
|
|
||||||
def get_intersections(grid):
|
def get_earliest_intersections(grid):
|
||||||
intersections = []
|
min_steps = 2**64
|
||||||
for x, line in grid.items():
|
for line in grid.values():
|
||||||
for y, wire_ids in line.items():
|
for wire_ids in line.values():
|
||||||
if len(wire_ids) > 1:
|
if len(wire_ids) > 1:
|
||||||
intersections.append((x, y))
|
steps = sum(s for _, s in wire_ids)
|
||||||
return intersections
|
if steps < min_steps:
|
||||||
|
min_steps = steps
|
||||||
|
return min_steps
|
||||||
|
|
||||||
def get_manhattan_distances(points):
|
|
||||||
distances = []
|
|
||||||
for point in points:
|
|
||||||
distances.append(manhattan_dist((0, 0), point))
|
|
||||||
return distances
|
|
||||||
|
|
||||||
def manhattan_dist(p1, p2):
|
|
||||||
p1x, p1y = p1
|
|
||||||
p2x, p2y = p2
|
|
||||||
return abs(p1x - p2x) + abs(p1y - p2y)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in a new issue