From 7a292b026dabe6bea58b7733374475295df56211 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Sat, 23 Jan 2021 17:30:37 +0100 Subject: [PATCH] Implement 2019 day 3 --- 2019/aoc2019/day03.py | 44 ++++++++++++++++++++++++++++++++++++++++ 2019/tests/test_day03.py | 25 +++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 2019/aoc2019/day03.py create mode 100644 2019/tests/test_day03.py diff --git a/2019/aoc2019/day03.py b/2019/aoc2019/day03.py new file mode 100644 index 0000000..9c0c272 --- /dev/null +++ b/2019/aoc2019/day03.py @@ -0,0 +1,44 @@ +import itertools +from typing import Dict, TextIO + + +def compute_points(line: str) -> Dict[complex, int]: + points: Dict[complex, int] = {} + steps = itertools.count(1) + + pos = complex(0) + + directions = { + 'U': 1j, + 'R': 1, + 'D': -1j, + 'L': -1, + } + + for move in line.strip().split(','): + direction = directions[move[0]] + + for _ in range(int(move[1:])): + pos += direction + + points.setdefault(pos, next(steps)) + + return points + + +def part1(data: TextIO) -> int: + points_a = compute_points(next(data)) + points_b = compute_points(next(data)) + + in_common = set(points_a.keys()) & set(points_b.keys()) + + return int(min(abs(c.imag) + abs(c.real) for c in in_common)) + + +def part2(data: TextIO) -> int: + points_a = compute_points(next(data)) + points_b = compute_points(next(data)) + + in_common = set(points_a.keys()) & set(points_b.keys()) + + return min(points_a[pos] + points_b[pos] for pos in in_common) diff --git a/2019/tests/test_day03.py b/2019/tests/test_day03.py new file mode 100644 index 0000000..7a691ae --- /dev/null +++ b/2019/tests/test_day03.py @@ -0,0 +1,25 @@ +from io import StringIO + +import pytest + +from aoc2019.day03 import part1, part2 + +SAMPLES = [ + "R8,U5,L5,D3\nU7,R6,D4,L4", + "R75,D30,R83,U83,L12,D49,R71,U7,L72\nU62,R66,U55,R34,D71,R55,D58,R83", + "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51\nU98,R91,D20,R16,D67,R40,U7,R15,U6,R7", +] + + +@pytest.mark.parametrize('paths,outcome', zip(SAMPLES, [6, 159, 135])) +def test_part1(paths: str, outcome: int): + path_data = StringIO(paths) + + assert part1(path_data) == outcome + + +@pytest.mark.parametrize('paths,outcome', zip(SAMPLES, [30, 610, 410])) +def test_part2(paths: str, outcome: int): + path_data = StringIO(paths) + + assert part2(path_data) == outcome