2021-12-05 - Hydrothermal Venture
(original .ipynb)
Day 5 puzzle input is a list of co-ordinate pairs that represent lines (mine is here). Part 1 involves finding how many points the horizontal and vertical lines cross at least twice. Part 2 involves the same but including diagonal lines too.
from collections import defaultdict
puzzle_input_str = open("puzzle_input/day5.txt").read()
test_input_str = """0,9 -> 5,9
8,0 -> 0,8
9,4 -> 3,4
2,2 -> 2,1
7,0 -> 7,4
6,4 -> 2,0
0,9 -> 2,9
3,4 -> 1,4
0,0 -> 8,8
5,5 -> 8,2"""
def parse_coord(coord):
x, y = coord.split(",")
return int(x), int(y)
def parse_lines(input_str):
for line in input_str.split("\n"):
p1, p2 = line.split(" -> ")
x1, y1 = parse_coord(p1)
x2, y2 = parse_coord(p2)
yield (x1, y1, x2, y2)
def is_diagonal(x1, y1, x2, y2):
return not(x1 == x2 or y1 == y2)
def find_step(p1, p2):
if p1 == p2:
return 0
return 1 if p2 > p1 else -1
def line_points(x1, y1, x2, y2):
dx = find_step(x1, x2)
dy = find_step(y1, y2)
while not (x1 == x2 and y1 == y2):
yield (x1, y1)
x1 += dx
y1 += dy
yield (x1, y1)
def find_visited_points(lines):
visited = defaultdict(lambda:0)
for line in lines:
for x, y in line_points(*line):
visited[(x,y)] += 1
return visited
def part_one(input_str):
lines = parse_lines(input_str)
visited = find_visited_points(line for line in lines if not is_diagonal(*line))
return sum(1 for n in visited.values() if n >= 2)
assert 5 == part_one(test_input_str)
print("part one:", part_one(puzzle_input_str))
part one: 5197
def part_two(input_str):
lines = parse_lines(input_str)
visited = find_visited_points(lines)
return sum(1 for n in visited.values() if n >= 2)
assert 12 == part_two(test_input_str)
print("part two:", part_two(puzzle_input_str))
part two: 18605