lots of cleanup

This commit is contained in:
Ruediger Ludwig 2022-12-10 19:30:10 +01:00
parent 7d0d3e504e
commit 0385cbd62e
26 changed files with 337 additions and 417 deletions

View file

@ -1,19 +1,19 @@
from __future__ import annotations
from dataclasses import dataclass
from typing import Iterator
from typing import Iterator, Self
day_num = 9
def part1(lines: Iterator[str]) -> int:
lst = [Command.parse(line) for line in lines]
return Command.walk(lst, 2)
commands = (Command.parse(line) for line in lines)
return simulate(commands, 2)
def part2(lines: Iterator[str]) -> int:
lst = [Command.parse(line) for line in lines]
return Command.walk(lst, 10)
commands = (Command.parse(line) for line in lines)
return simulate(commands, 10)
@dataclass(frozen=True, slots=True)
@ -21,18 +21,18 @@ class Point:
x: int
y: int
@staticmethod
def parse_direction(char: str) -> Point:
@classmethod
def parse_direction(cls, char: str) -> Self:
""" Parses the given direction to a Point. May raise if invalid """
match char:
case 'R':
return Point(1, 0)
return cls(1, 0)
case 'U':
return Point(0, 1)
return cls(0, 1)
case 'L':
return Point(-1, 0)
return cls(-1, 0)
case 'D':
return Point(0, -1)
return cls(0, -1)
case _:
raise Exception(f"Unkown Direction: {char}")
@ -65,8 +65,8 @@ class Command:
dir: Point
steps: int
@staticmethod
def parse(line: str) -> Command:
@classmethod
def parse(cls, line: str) -> Self:
""" Parse a command line. My raise exception if the was an illegal line"""
match line.split():
case [dir, steps]:
@ -74,20 +74,20 @@ class Command:
case _:
raise Exception(f"Illegal line: {line}")
@staticmethod
def walk(lst: list[Command], rope_length: int):
""" Walks the whole rope in Planck length steps according to commands """
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)
def simulate(lst: Iterator[Command], rope_length: int) -> int:
""" Walks the whole rope in Planck length steps according to commands """
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

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