Day 3 part 2

This commit is contained in:
Dece 2019-12-15 16:35:33 +01:00
parent aeaec72182
commit 8ca85d8ea5

View file

@ -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()