This commit is contained in:
Christoph Stahl 2023-12-09 12:03:41 +01:00
parent 9364a582c3
commit 4e47570718
3 changed files with 61 additions and 24 deletions

View file

@ -31,8 +31,7 @@ class Hand:
value_amount = list(
reversed(
sorted(
list([v for k, v in self.cards_dict.items() if k != joker]))
sorted(list([v for k, v in self.cards_dict.items() if k != joker]))
)
)
joker_amount = 0
@ -73,16 +72,14 @@ class Day07(Aoc2[list[tuple[Hand, int]], list[tuple[Hand, int]]]):
def parseinput1(self, inpt: str) -> list[tuple[Hand, int]]:
lines = inpt.splitlines()
return [
(Hand(line.split(" ")[0], "23456789TJQKA"),
int(line.split(" ")[1]))
(Hand(line.split(" ")[0], "23456789TJQKA"), int(line.split(" ")[1]))
for line in lines
]
def parseinput2(self, inpt: str) -> list[tuple[Hand, int]]:
lines = inpt.splitlines()
return [
(Hand(line.split(" ")[0], "J23456789TQKA", "J"), int(
line.split(" ")[1]))
(Hand(line.split(" ")[0], "J23456789TQKA", "J"), int(line.split(" ")[1]))
for line in lines
]

View file

@ -1,4 +1,5 @@
from __future__ import annotations
from dataclasses import dataclass
import itertools
import math
from typing import Optional
@ -6,18 +7,23 @@ from typing import Optional
from .aoc import Aoc2, AocSameParser
@dataclass
class Map:
def __init__(self, inpt: str) -> None:
directions: list[int]
rules: dict[str, tuple[str, str]]
@staticmethod
def from_input(inpt: str) -> Map:
lines = inpt.splitlines()
self.directions: list[int] = [0 if rl == "L" else 1 for rl in lines[0]]
self.rules = {line[:3]: (line[7:10], line[12:15]) for line in lines[2:]}
directions: list[int] = [0 if rl == "L" else 1 for rl in lines[0]]
rules = {line[:3]: (line[7:10], line[12:15]) for line in lines[2:]}
return Map(directions, rules)
class Day08(AocSameParser[Map], Aoc2[Map, Map]):
def parseinput(self, inpt: str) -> Map:
return Map(inpt)
return Map.from_input(inpt)
def part1(self, inpt: Map) -> int:
current = "AAA"
@ -25,21 +31,20 @@ class Day08(AocSameParser[Map], Aoc2[Map, Map]):
for steps, direction in enumerate(itertools.cycle(inpt.directions)):
if current == "ZZZ":
return steps
else:
current = inpt.rules[current][direction]
current = inpt.rules[current][direction]
raise RuntimeError("End of the rainbow")
def find_loop(self, list_of_nrs: list[int]) -> Optional[tuple[int, int]]:
for index in range(len(list_of_nrs)):
for index in range(len(list_of_nrs[index + 1 :])):
diff = list_of_nrs[index + 1] - list_of_nrs[index]
if list_of_nrs[index + 1] + diff in list_of_nrs:
return list_of_nrs[index], diff
for index, nr in enumerate(list_of_nrs):
for nr2 in list_of_nrs[index + 1 :]:
diff = nr2 - nr
if nr2 + diff in list_of_nrs:
return nr, diff
return None
def part2(self, inpt: Map) -> int:
current = [node for node in inpt.rules.keys() if node.endswith("A")]
steps_to_z = [[] for _ in current]
steps_to_z: list[list[int]] = [[] for _ in current]
loops: list[Optional[tuple[int, int]]] = [None for _ in current]
for steps, direction in enumerate(itertools.cycle(inpt.directions)):
@ -50,17 +55,14 @@ class Day08(AocSameParser[Map], Aoc2[Map, Map]):
if not any(loop is None for loop in loops):
break
else:
current = [inpt.rules[node][direction] for node in current]
current = [inpt.rules[node][direction] for node in current]
# Turns out, each path directly loops :/
return math.lcm(*(loop[0] for loop in loops if loop is not None))
def main() -> None:
day08 = Day08(2023, 8)
day08._example_code_nr1 = 1
day08._example_code_nr2 = -1
day08 = Day08(2023, 8, example_code_nr1=1, example_code_nr2=-1)
day08.run()

38
aoc/day09.py Normal file
View file

@ -0,0 +1,38 @@
from functools import reduce
from typing import Iterable
from .aoc import Aoc2, AocParseLinesSameParser
class Day09(AocParseLinesSameParser[list[int]], Aoc2[list[list[int]], list[list[int]]]):
def parseline(self, inpt: str) -> list[int]:
return [int(d) for d in inpt.split(" ")]
def derive(self, init: list[int]) -> list[int]:
return [y - x for x, y in zip(init, init[1:])]
def get_nth_value_in_deriv(self, values: list[int], n: int) -> Iterable[int]:
while any(values):
yield values[n]
values = self.derive(values)
def part1(self, inpt: list[list[int]]) -> int:
return sum(sum(self.get_nth_value_in_deriv(line, -1)) for line in inpt)
def part2(self, inpt: list[list[int]]) -> int:
return sum(
reduce(
lambda acc, x: x - acc,
reversed(list(self.get_nth_value_in_deriv(line, 0))),
)
for line in inpt
)
def main() -> None:
day09 = Day09(2023, 9, example_code_nr2=0)
day09.run()
if __name__ == "__main__":
main()