day09 finished

This commit is contained in:
Ruediger Ludwig 2022-12-09 07:32:42 +01:00
parent a60707185f
commit 3629b81bcf
7 changed files with 2150 additions and 0 deletions

View file

@ -8,6 +8,7 @@ I use python 3.11 without any libraries beyond the standard.
| Day | Time | Rank | Score | Time | Rank | Score | | Day | Time | Rank | Score | Time | Rank | Score |
| --- | --------- | ----- | ----- | -------- | ----- | ----- | | --- | --------- | ----- | ----- | -------- | ----- | ----- |
| 9 | 00:54:18 | 7719 | 0 | 01:07:37 | 4901 | 0 |
| 8 | 00:41:51 | 7831 | 0 | 00:59:27 | 6325 | 0 | | 8 | 00:41:51 | 7831 | 0 | 00:59:27 | 6325 | 0 |
| 7 | 00:34:59 | 2683 | 0 | 00:45:45 | 2943 | 0 | | 7 | 00:34:59 | 2683 | 0 | 00:45:45 | 2943 | 0 |
| 6 | 00:14:52 | 9153 | 0 | 00:17:06 | 8413 | 0 | | 6 | 00:14:52 | 9153 | 0 | 00:17:06 | 8413 | 0 |

View file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,8 @@
R 4
U 4
L 3
D 1
R 4
D 1
L 5
R 2

View file

@ -0,0 +1,8 @@
R 5
U 8
L 8
D 3
R 17
D 10
L 25
U 20

View file

@ -0,0 +1,92 @@
from __future__ import annotations
from dataclasses import dataclass
from typing import Iterator
day_num = 9
def part1(lines: Iterator[str]) -> int:
lst = [Command.parse(line) for line in lines]
return Command.walk(lst, 2)
def part2(lines: Iterator[str]) -> int:
lst = [Command.parse(line) for line in lines]
return Command.walk(lst, 10)
@dataclass(frozen=True, slots=True)
class Point:
x: int
y: int
@staticmethod
def parse_direction(char: str) -> Point:
""" Parses the given direction to a Point. May raise if invalid """
match char:
case 'R':
return Point(1, 0)
case 'U':
return Point(0, 1)
case 'L':
return Point(-1, 0)
case 'D':
return Point(0, -1)
case _:
raise Exception(f"Unkown Direction: {char}")
def add(self, other: Point) -> Point:
return Point(self.x + other.x, self.y + other.y)
def sub(self, other: Point) -> Point:
return Point(self.x - other.x, self.y - other.y)
def is_unit(self) -> bool:
""" return true, if this discribes any point (diagonally) adjacent to the origin"""
return abs(self.x) <= 1 and abs(self.y) <= 1
def as_unit(self) -> Point:
""" Compresses this Point to a point with unit components """
def unit(num: int) -> int:
return 0 if num == 0 else num // abs(num)
return Point(unit(self.x), unit(self.y))
def step_to(self, other: Point) -> Point | None:
diff = other.sub(self)
if diff.is_unit():
return None
return self.add(diff.as_unit())
@dataclass(frozen=True, slots=True)
class Command:
dir: Point
steps: int
@staticmethod
def parse(line: str) -> Command:
""" Parse a command line. My raise exception if the was an illegal line"""
match line.split():
case [dir, steps]:
return Command(Point.parse_direction(dir), int(steps))
case _:
raise Exception(f"Illegal line: {line}")
@staticmethod
def walk(lst: list[Command], rope_length: int):
""" Walks the whole rope in Planck length steps """
rope = [Point(0, 0)] * rope_length
visited = {rope[-1]}
for command in lst:
for _ in range(command.steps):
rope[0] = rope[0].add(command.dir)
for n in range(1, rope_length):
moved_piece = rope[n].step_to(rope[n - 1])
if not moved_piece:
break
rope[n] = moved_piece
if n == rope_length - 1:
visited.add(rope[n])
return len(visited)

View file

@ -0,0 +1,41 @@
from advent.common import utils
from .solution import Command, day_num, part1, part2
def test_part1():
data = utils.read_data(day_num, 'test01.txt')
expected = 13
result = part1(data)
assert result == expected
def test_part2():
data = utils.read_data(day_num, 'test02.txt')
expected = 36
result = part2(data)
assert result == expected
def test_short():
data = utils.read_data(day_num, 'test01.txt')
expected = 13
lst = [Command.parse(line) for line in data]
result = Command.walk(lst, 2)
assert result == expected
def test_long1():
data = utils.read_data(day_num, 'test01.txt')
expected = 1
lst = [Command.parse(line) for line in data]
result = Command.walk(lst, 10)
assert result == expected
def test_long2():
data = utils.read_data(day_num, 'test02.txt')
expected = 36
lst = [Command.parse(line) for line in data]
result = Command.walk(lst, 10)
assert result == expected