Speed improvements and time measurement

This commit is contained in:
Christoph Stahl 2023-12-12 12:11:06 +01:00
parent 0f233f8324
commit 8197d2a3df
3 changed files with 54 additions and 41 deletions

View file

@ -4,6 +4,7 @@ from typing import Any, Generic, Protocol, TypeVar
from urllib.request import Request, urlopen
from html.parser import HTMLParser
from importlib import import_module
from timeit import default_timer
T1 = TypeVar("T1")
T2 = TypeVar("T2")
@ -187,7 +188,10 @@ def run_latest() -> None:
]
day = days[-1]
print(f"Running {day.__name__}")
s_time = default_timer()
day.main()
e_time = default_timer()
print(f"Time: {e_time-s_time}")
def main() -> None:
@ -196,10 +200,16 @@ def main() -> None:
for file in sorted(Path("aoc").iterdir())
if file.name.endswith(".py") and file.name.startswith("day")
]
b_time = default_timer()
for day in days:
print(f"Running {day.__name__}")
s_time = default_timer()
day.main()
e_time = default_timer()
print(f"Time: {e_time-s_time}")
print()
f_time = default_timer()
print(f"Overall time: {f_time - b_time}")
if __name__ == "__main__":

View file

@ -44,21 +44,19 @@ class Day08(AocSameParser[Map], Aoc2[Map, Map]):
def part2(self, inpt: Map) -> int:
current = [node for node in inpt.rules.keys() if node.endswith("A")]
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)):
steps_to_z = [0] * len(current)
for direction in itertools.cycle(inpt.directions):
dirty = False
for n, node in enumerate(current):
if node.endswith("Z"):
steps_to_z[n].append(steps)
loops[n] = self.find_loop(steps_to_z[n])
if not any(loop is None for loop in loops):
continue
dirty = True
steps_to_z[n] += 1
current[n] = inpt.rules[node][direction]
if not dirty:
break
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))
return math.lcm(*steps_to_z)
def main() -> None:

View file

@ -1,8 +1,9 @@
from __future__ import annotations
from array import array
from collections.abc import Iterable
from collections.abc import Callable, Iterable
from dataclasses import dataclass
from itertools import accumulate, combinations
from .aoc import Aoc2, AocSameParser
@ -64,43 +65,50 @@ class Matrix:
return "\n".join((x.tounicode() for x in self.iter_rows()))
def finditer(self, element: str) -> Iterable[Position]:
for y, line in enumerate(self.iter_rows()):
for x, char in enumerate(line):
if char == element:
yield Position(x, y)
return (
Position(x, y)
for y, line in enumerate(self.iter_rows())
for x, char in enumerate(line)
if char == element
)
def filter_row_ids(self, predicate: Callable[[array[str]], bool]) -> Iterable[int]:
return (y for y, row in enumerate(self.iter_rows()) if predicate(row))
def filter_col_ids(self, predicate: Callable[[array[str]], bool]) -> Iterable[int]:
return (x for x, col in enumerate(self.iter_cols()) if predicate(col))
@dataclass
class Map:
map: Matrix
galaxies: list[Position]
adjusted_galaxies: list[Position]
large_adjusted_galaxies: list[Position]
galaxies: Iterable[tuple[Position, Position]]
@classmethod
def from_input(cls, inpt: str) -> Map:
matrix = Matrix(inpt)
missing_xs = array(
"I",
accumulate([1 if col.count("#") == 0 else 0 for col in matrix.iter_cols()]),
)
galaxies = list(matrix.finditer("#"))
missing_ys = [
y for y, row in enumerate(matrix.iter_rows()) if row.count("#") == 0
]
missing_xs = [
x for x, col in enumerate(matrix.iter_cols()) if col.count("#") == 0
]
missing_ys = array(
"I",
accumulate([1 if row.count("#") == 0 else 0 for row in matrix.iter_rows()]),
)
adjusted_galaxies = []
large_adjusted_galaxies = []
for pos in galaxies:
offset = Position(
len([m for m in missing_xs if m < pos.x]),
len([m for m in missing_ys if m < pos.y]),
offset_galaxies = (
(
Position(
missing_xs[pos.x],
missing_ys[pos.y],
),
pos,
)
adjusted_galaxies.append(pos + offset)
large_adjusted_galaxies.append(pos + 999_999 * offset)
for pos in matrix.finditer("#")
)
return cls(matrix, galaxies, adjusted_galaxies, large_adjusted_galaxies)
return cls(matrix, offset_galaxies)
class Day11(AocSameParser[Map], Aoc2[Map, Map]):
@ -109,16 +117,13 @@ class Day11(AocSameParser[Map], Aoc2[Map, Map]):
def part1(self, inpt: Map) -> int:
return sum(
g1 | g2
for i, g1 in enumerate(inpt.adjusted_galaxies)
for g2 in inpt.adjusted_galaxies[i + 1 :]
g1 | g2 for g1, g2 in combinations(((o + g) for o, g in inpt.galaxies), 2)
)
def part2(self, inpt: Map) -> int:
return sum(
g1 | g2
for i, g1 in enumerate(inpt.large_adjusted_galaxies)
for g2 in inpt.large_adjusted_galaxies[i + 1 :]
for g1, g2 in combinations(((999_999 * o + g) for o, g in inpt.galaxies), 2)
)