Start fixing 2022 for new API.
This commit is contained in:
		@@ -1,7 +1,12 @@
 | 
				
			|||||||
import sys
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
blocks = sys.stdin.read().split("\n\n")
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Solver(BaseSolver):
 | 
				
			||||||
 | 
					    def solve(self, input: str) -> Iterator[Any]:
 | 
				
			||||||
 | 
					        blocks = input.split("\n\n")
 | 
				
			||||||
        values = sorted(sum(map(int, block.split())) for block in blocks)
 | 
					        values = sorted(sum(map(int, block.split())) for block in blocks)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
print(f"answer 1 is {values[-1]}")
 | 
					        yield values[-1]
 | 
				
			||||||
print(f"answer 2 is {sum(values[-3:])}")
 | 
					        yield sum(values[-3:])
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,13 @@
 | 
				
			|||||||
import sys
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lines = sys.stdin.read().splitlines()
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cycle = 1
 | 
					 | 
				
			||||||
x = 1
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Solver(BaseSolver):
 | 
				
			||||||
 | 
					    def solve(self, input: str) -> Iterator[Any]:
 | 
				
			||||||
 | 
					        lines = [line.strip() for line in input.splitlines()]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cycle, x = 1, 1
 | 
				
			||||||
        values = {cycle: x}
 | 
					        values = {cycle: x}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for line in lines:
 | 
					        for line in lines:
 | 
				
			||||||
@@ -23,16 +26,18 @@ for line in lines:
 | 
				
			|||||||
            values[cycle] = x
 | 
					            values[cycle] = x
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        answer_1 = sum(c * values[c] for c in range(20, max(values.keys()) + 1, 40))
 | 
					        answer_1 = sum(c * values[c] for c in range(20, max(values.keys()) + 1, 40))
 | 
				
			||||||
print(f"answer 1 is {answer_1}")
 | 
					        yield answer_1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        yield (
 | 
				
			||||||
for i in range(6):
 | 
					            "\n"
 | 
				
			||||||
    for j in range(40):
 | 
					            + "\n".join(
 | 
				
			||||||
        v = values[1 + i * 40 + j]
 | 
					                "".join(
 | 
				
			||||||
 | 
					                    "#"
 | 
				
			||||||
        if j >= v - 1 and j <= v + 1:
 | 
					                    if j >= (v := values[1 + i * 40 + j]) - 1 and j <= v + 1
 | 
				
			||||||
            print("#", end="")
 | 
					                    else "."
 | 
				
			||||||
        else:
 | 
					                    for j in range(40)
 | 
				
			||||||
            print(".", end="")
 | 
					                )
 | 
				
			||||||
 | 
					                for i in range(6)
 | 
				
			||||||
    print()
 | 
					            )
 | 
				
			||||||
 | 
					            + "\n"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,8 @@
 | 
				
			|||||||
import copy
 | 
					import copy
 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
from functools import reduce
 | 
					from functools import reduce
 | 
				
			||||||
from typing import Callable, Final, Mapping, Sequence
 | 
					from typing import Any, Callable, Final, Iterator, Mapping, Sequence
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Monkey:
 | 
					class Monkey:
 | 
				
			||||||
@@ -119,13 +120,14 @@ def monkey_business(inspects: dict[Monkey, int]) -> int:
 | 
				
			|||||||
    return sorted_levels[-2] * sorted_levels[-1]
 | 
					    return sorted_levels[-2] * sorted_levels[-1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
monkeys = [parse_monkey(block.splitlines()) for block in sys.stdin.read().split("\n\n")]
 | 
					class Solver(BaseSolver):
 | 
				
			||||||
 | 
					    def solve(self, input: str) -> Iterator[Any]:
 | 
				
			||||||
 | 
					        monkeys = [parse_monkey(block.splitlines()) for block in input.split("\n\n")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # case 1: we simply divide the worry by 3 after applying the monkey worry operation
 | 
					        # case 1: we simply divide the worry by 3 after applying the monkey worry operation
 | 
				
			||||||
answer_1 = monkey_business(
 | 
					        yield monkey_business(
 | 
				
			||||||
            run(copy.deepcopy(monkeys), 20, me_worry_fn=lambda w: w // 3)
 | 
					            run(copy.deepcopy(monkeys), 20, me_worry_fn=lambda w: w // 3)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
print(f"answer 1 is {answer_1}")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # case 2: to keep reasonable level values, we can use a modulo operation, we need to
 | 
					        # case 2: to keep reasonable level values, we can use a modulo operation, we need to
 | 
				
			||||||
        # use the product of all "divisible by" test so that the test remains valid
 | 
					        # use the product of all "divisible by" test so that the test remains valid
 | 
				
			||||||
@@ -136,7 +138,10 @@ print(f"answer 1 is {answer_1}")
 | 
				
			|||||||
        # we use the product of all test value
 | 
					        # we use the product of all test value
 | 
				
			||||||
        #
 | 
					        #
 | 
				
			||||||
        total_test_value = reduce(lambda w, m: w * m.test_value, monkeys, 1)
 | 
					        total_test_value = reduce(lambda w, m: w * m.test_value, monkeys, 1)
 | 
				
			||||||
answer_2 = monkey_business(
 | 
					        yield monkey_business(
 | 
				
			||||||
    run(copy.deepcopy(monkeys), 10_000, me_worry_fn=lambda w: w % total_test_value)
 | 
					            run(
 | 
				
			||||||
 | 
					                copy.deepcopy(monkeys),
 | 
				
			||||||
 | 
					                10_000,
 | 
				
			||||||
 | 
					                me_worry_fn=lambda w: w % total_test_value,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
print(f"answer 2 is {answer_2}")
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
import heapq
 | 
					import heapq
 | 
				
			||||||
import sys
 | 
					from typing import Any, Callable, Iterator, TypeVar
 | 
				
			||||||
from typing import Callable, Iterator, TypeVar
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Node = TypeVar("Node")
 | 
					Node = TypeVar("Node")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -68,30 +69,6 @@ def make_path(parents: dict[Node, Node], start: Node, end: Node) -> list[Node] |
 | 
				
			|||||||
    return list(reversed(path))
 | 
					    return list(reversed(path))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def print_path(path: list[tuple[int, int]], n_rows: int, n_cols: int) -> None:
 | 
					 | 
				
			||||||
    end = path[-1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    graph = [["." for _c in range(n_cols)] for _r in range(n_rows)]
 | 
					 | 
				
			||||||
    graph[end[0]][end[1]] = "E"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for i in range(0, len(path) - 1):
 | 
					 | 
				
			||||||
        cr, cc = path[i]
 | 
					 | 
				
			||||||
        nr, nc = path[i + 1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if cr == nr and nc == cc - 1:
 | 
					 | 
				
			||||||
            graph[cr][cc] = "<"
 | 
					 | 
				
			||||||
        elif cr == nr and nc == cc + 1:
 | 
					 | 
				
			||||||
            graph[cr][cc] = ">"
 | 
					 | 
				
			||||||
        elif cr == nr - 1 and nc == cc:
 | 
					 | 
				
			||||||
            graph[cr][cc] = "v"
 | 
					 | 
				
			||||||
        elif cr == nr + 1 and nc == cc:
 | 
					 | 
				
			||||||
            graph[cr][cc] = "^"
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            assert False, "{} -> {} infeasible".format(path[i], path[i + 1])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    print("\n".join("".join(row) for row in graph))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def neighbors(
 | 
					def neighbors(
 | 
				
			||||||
    grid: list[list[int]], node: tuple[int, int], up: bool
 | 
					    grid: list[list[int]], node: tuple[int, int], up: bool
 | 
				
			||||||
) -> Iterator[tuple[int, int]]:
 | 
					) -> Iterator[tuple[int, int]]:
 | 
				
			||||||
@@ -118,7 +95,34 @@ def neighbors(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# === main code ===
 | 
					# === main code ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lines = sys.stdin.read().splitlines()
 | 
					
 | 
				
			||||||
 | 
					class Solver(BaseSolver):
 | 
				
			||||||
 | 
					    def print_path(self, path: list[tuple[int, int]], n_rows: int, n_cols: int) -> None:
 | 
				
			||||||
 | 
					        end = path[-1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        graph = [["." for _c in range(n_cols)] for _r in range(n_rows)]
 | 
				
			||||||
 | 
					        graph[end[0]][end[1]] = "E"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for i in range(0, len(path) - 1):
 | 
				
			||||||
 | 
					            cr, cc = path[i]
 | 
				
			||||||
 | 
					            nr, nc = path[i + 1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if cr == nr and nc == cc - 1:
 | 
				
			||||||
 | 
					                graph[cr][cc] = "<"
 | 
				
			||||||
 | 
					            elif cr == nr and nc == cc + 1:
 | 
				
			||||||
 | 
					                graph[cr][cc] = ">"
 | 
				
			||||||
 | 
					            elif cr == nr - 1 and nc == cc:
 | 
				
			||||||
 | 
					                graph[cr][cc] = "v"
 | 
				
			||||||
 | 
					            elif cr == nr + 1 and nc == cc:
 | 
				
			||||||
 | 
					                graph[cr][cc] = "^"
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                assert False, "{} -> {} infeasible".format(path[i], path[i + 1])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for row in graph:
 | 
				
			||||||
 | 
					            self.logger.info("".join(row))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def solve(self, input: str) -> Iterator[Any]:
 | 
				
			||||||
 | 
					        lines = input.splitlines()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        grid = [[ord(cell) - ord("a") for cell in line] for line in lines]
 | 
					        grid = [[ord(cell) - ord("a") for cell in line] for line in lines]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -145,19 +149,20 @@ assert end is not None
 | 
				
			|||||||
        grid[start[0]][start[1]] = 0
 | 
					        grid[start[0]][start[1]] = 0
 | 
				
			||||||
        grid[end[0]][end[1]] = ord("z") - ord("a")
 | 
					        grid[end[0]][end[1]] = ord("z") - ord("a")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
        lengths_1, parents_1 = dijkstra(
 | 
					        lengths_1, parents_1 = dijkstra(
 | 
				
			||||||
    start=start, neighbors=lambda n: neighbors(grid, n, True), cost=lambda lhs, rhs: 1
 | 
					            start=start,
 | 
				
			||||||
 | 
					            neighbors=lambda n: neighbors(grid, n, True),
 | 
				
			||||||
 | 
					            cost=lambda lhs, rhs: 1,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        path_1 = make_path(parents_1, start, end)
 | 
					        path_1 = make_path(parents_1, start, end)
 | 
				
			||||||
        assert path_1 is not None
 | 
					        assert path_1 is not None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
print_path(path_1, n_rows=len(grid), n_cols=len(grid[0]))
 | 
					        self.print_path(path_1, n_rows=len(grid), n_cols=len(grid[0]))
 | 
				
			||||||
 | 
					        yield lengths_1[end] - 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
print(f"answer 1 is {lengths_1[end] - 1}")
 | 
					        lengths_2, _ = dijkstra(
 | 
				
			||||||
 | 
					            start=end,
 | 
				
			||||||
lengths_2, parents_2 = dijkstra(
 | 
					            neighbors=lambda n: neighbors(grid, n, False),
 | 
				
			||||||
    start=end, neighbors=lambda n: neighbors(grid, n, False), cost=lambda lhs, rhs: 1
 | 
					            cost=lambda lhs, rhs: 1,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
answer_2 = min(lengths_2.get(start, float("inf")) for start in start_s)
 | 
					        yield min(lengths_2.get(start, float("inf")) for start in start_s)
 | 
				
			||||||
print(f"answer 2 is {answer_2}")
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,8 @@
 | 
				
			|||||||
import json
 | 
					import json
 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
from functools import cmp_to_key
 | 
					from functools import cmp_to_key
 | 
				
			||||||
from typing import TypeAlias, cast
 | 
					from typing import Any, Iterator, TypeAlias, cast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
blocks = sys.stdin.read().strip().split("\n\n")
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					 | 
				
			||||||
pairs = [tuple(json.loads(p) for p in block.split("\n")) for block in blocks]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Packet: TypeAlias = list[int | list["Packet"]]
 | 
					Packet: TypeAlias = list[int | list["Packet"]]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -28,8 +25,12 @@ def compare(lhs: Packet, rhs: Packet) -> int:
 | 
				
			|||||||
    return len(rhs) - len(lhs)
 | 
					    return len(rhs) - len(lhs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
answer_1 = sum(i + 1 for i, (lhs, rhs) in enumerate(pairs) if compare(lhs, rhs) > 0)
 | 
					class Solver(BaseSolver):
 | 
				
			||||||
print(f"answer_1 is {answer_1}")
 | 
					    def solve(self, input: str) -> Iterator[Any]:
 | 
				
			||||||
 | 
					        blocks = input.split("\n\n")
 | 
				
			||||||
 | 
					        pairs = [tuple(json.loads(p) for p in block.split("\n")) for block in blocks]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        yield sum(i + 1 for i, (lhs, rhs) in enumerate(pairs) if compare(lhs, rhs) > 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dividers = [[[2]], [[6]]]
 | 
					        dividers = [[[2]], [[6]]]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -38,4 +39,4 @@ packets.extend(dividers)
 | 
				
			|||||||
        packets = list(reversed(sorted(packets, key=cmp_to_key(compare))))
 | 
					        packets = list(reversed(sorted(packets, key=cmp_to_key(compare))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        d_index = [packets.index(d) + 1 for d in dividers]
 | 
					        d_index = [packets.index(d) + 1 for d in dividers]
 | 
				
			||||||
print(f"answer 2 is {d_index[0] * d_index[1]}")
 | 
					        yield d_index[0] * d_index[1]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
import sys
 | 
					 | 
				
			||||||
from enum import Enum, auto
 | 
					from enum import Enum, auto
 | 
				
			||||||
from typing import Callable, cast
 | 
					from typing import Any, Callable, Iterator, cast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Cell(Enum):
 | 
					class Cell(Enum):
 | 
				
			||||||
@@ -12,26 +13,6 @@ class Cell(Enum):
 | 
				
			|||||||
        return {Cell.AIR: ".", Cell.ROCK: "#", Cell.SAND: "O"}[self]
 | 
					        return {Cell.AIR: ".", Cell.ROCK: "#", Cell.SAND: "O"}[self]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def print_blocks(blocks: dict[tuple[int, int], Cell]):
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    Print the given set of blocks on a grid.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Args:
 | 
					 | 
				
			||||||
        blocks: Set of blocks to print.
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    x_min, y_min, x_max, y_max = (
 | 
					 | 
				
			||||||
        min(x for x, _ in blocks),
 | 
					 | 
				
			||||||
        0,
 | 
					 | 
				
			||||||
        max(x for x, _ in blocks),
 | 
					 | 
				
			||||||
        max(y for _, y in blocks),
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for y in range(y_min, y_max + 1):
 | 
					 | 
				
			||||||
        print(
 | 
					 | 
				
			||||||
            "".join(str(blocks.get((x, y), Cell.AIR)) for x in range(x_min, x_max + 1))
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def flow(
 | 
					def flow(
 | 
				
			||||||
    blocks: dict[tuple[int, int], Cell],
 | 
					    blocks: dict[tuple[int, int], Cell],
 | 
				
			||||||
    stop_fn: Callable[[int, int], bool],
 | 
					    stop_fn: Callable[[int, int], bool],
 | 
				
			||||||
@@ -84,19 +65,44 @@ def flow(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# === inputs ===
 | 
					# === inputs ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lines = sys.stdin.read().splitlines()
 | 
					
 | 
				
			||||||
 | 
					class Solver(BaseSolver):
 | 
				
			||||||
 | 
					    def print_blocks(self, blocks: dict[tuple[int, int], Cell]):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Print the given set of blocks on a grid.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Args:
 | 
				
			||||||
 | 
					            blocks: Set of blocks to print.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        x_min, y_min, x_max, y_max = (
 | 
				
			||||||
 | 
					            min(x for x, _ in blocks),
 | 
				
			||||||
 | 
					            0,
 | 
				
			||||||
 | 
					            max(x for x, _ in blocks),
 | 
				
			||||||
 | 
					            max(y for _, y in blocks),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for y in range(y_min, y_max + 1):
 | 
				
			||||||
 | 
					            self.logger.info(
 | 
				
			||||||
 | 
					                "".join(
 | 
				
			||||||
 | 
					                    str(blocks.get((x, y), Cell.AIR)) for x in range(x_min, x_max + 1)
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def solve(self, input: str) -> Iterator[Any]:
 | 
				
			||||||
 | 
					        lines = [line.strip() for line in input.splitlines()]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        paths: list[list[tuple[int, int]]] = []
 | 
					        paths: list[list[tuple[int, int]]] = []
 | 
				
			||||||
        for line in lines:
 | 
					        for line in lines:
 | 
				
			||||||
            parts = line.split(" -> ")
 | 
					            parts = line.split(" -> ")
 | 
				
			||||||
            paths.append(
 | 
					            paths.append(
 | 
				
			||||||
                [
 | 
					                [
 | 
				
			||||||
            cast(tuple[int, int], tuple(int(c.strip()) for c in part.split(",")))
 | 
					                    cast(
 | 
				
			||||||
 | 
					                        tuple[int, int], tuple(int(c.strip()) for c in part.split(","))
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
                    for part in parts
 | 
					                    for part in parts
 | 
				
			||||||
                ]
 | 
					                ]
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
        blocks: dict[tuple[int, int], Cell] = {}
 | 
					        blocks: dict[tuple[int, int], Cell] = {}
 | 
				
			||||||
        for path in paths:
 | 
					        for path in paths:
 | 
				
			||||||
            for start, end in zip(path[:-1], path[1:]):
 | 
					            for start, end in zip(path[:-1], path[1:]):
 | 
				
			||||||
@@ -109,24 +115,17 @@ for path in paths:
 | 
				
			|||||||
                    for y in range(y_start, y_end):
 | 
					                    for y in range(y_start, y_end):
 | 
				
			||||||
                        blocks[x, y] = Cell.ROCK
 | 
					                        blocks[x, y] = Cell.ROCK
 | 
				
			||||||
 | 
					
 | 
				
			||||||
print_blocks(blocks)
 | 
					        self.print_blocks(blocks)
 | 
				
			||||||
print()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
x_min, y_min, x_max, y_max = (
 | 
					        y_max = max(y for _, y in blocks)
 | 
				
			||||||
    min(x for x, _ in blocks),
 | 
					 | 
				
			||||||
    0,
 | 
					 | 
				
			||||||
    max(x for x, _ in blocks),
 | 
					 | 
				
			||||||
    max(y for _, y in blocks),
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # === part 1 ===
 | 
					        # === part 1 ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        blocks_1 = flow(
 | 
					        blocks_1 = flow(
 | 
				
			||||||
            blocks.copy(), stop_fn=lambda x, y: y > y_max, fill_fn=lambda x, y: Cell.AIR
 | 
					            blocks.copy(), stop_fn=lambda x, y: y > y_max, fill_fn=lambda x, y: Cell.AIR
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
print_blocks(blocks_1)
 | 
					        self.print_blocks(blocks_1)
 | 
				
			||||||
print(f"answer 1 is {sum(v == Cell.SAND for v in blocks_1.values())}")
 | 
					        yield sum(v == Cell.SAND for v in blocks_1.values())
 | 
				
			||||||
print()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # === part 2 ===
 | 
					        # === part 2 ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -136,5 +135,5 @@ blocks_2 = flow(
 | 
				
			|||||||
            fill_fn=lambda x, y: Cell.AIR if y < y_max + 2 else Cell.ROCK,
 | 
					            fill_fn=lambda x, y: Cell.AIR if y < y_max + 2 else Cell.ROCK,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        blocks_2[500, 0] = Cell.SAND
 | 
					        blocks_2[500, 0] = Cell.SAND
 | 
				
			||||||
print_blocks(blocks_2)
 | 
					        self.print_blocks(blocks_2)
 | 
				
			||||||
print(f"answer 2 is {sum(v == Cell.SAND for v in blocks_2.values())}")
 | 
					        yield sum(v == Cell.SAND for v in blocks_2.values())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,3 @@
 | 
				
			|||||||
import sys
 | 
					 | 
				
			||||||
from typing import Any, Iterator
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import numpy as np
 | 
					import numpy as np
 | 
				
			||||||
@@ -62,8 +61,9 @@ class Solver(BaseSolver):
 | 
				
			|||||||
        for (sx, sy), (bx, by) in sensor_to_beacon.items():
 | 
					        for (sx, sy), (bx, by) in sensor_to_beacon.items():
 | 
				
			||||||
            d = abs(sx - bx) + abs(sy - by)
 | 
					            d = abs(sx - bx) + abs(sy - by)
 | 
				
			||||||
            m.add_constraint(
 | 
					            m.add_constraint(
 | 
				
			||||||
                m.abs(x - sx) + m.abs(y - sy) >= d + 1, ctname=f"ct_{sx}_{sy}"
 | 
					                m.abs(x - sx) + m.abs(y - sy) >= d + 1,  # type: ignore
 | 
				
			||||||
            )  # type: ignore
 | 
					                ctname=f"ct_{sx}_{sy}",
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        m.set_objective("min", x + y)
 | 
					        m.set_objective("min", x + y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,10 +5,12 @@ import itertools
 | 
				
			|||||||
import re
 | 
					import re
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
from collections import defaultdict
 | 
					from collections import defaultdict
 | 
				
			||||||
from typing import FrozenSet, NamedTuple
 | 
					from typing import Any, FrozenSet, Iterator, NamedTuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from tqdm import tqdm
 | 
					from tqdm import tqdm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Pipe(NamedTuple):
 | 
					class Pipe(NamedTuple):
 | 
				
			||||||
    name: str
 | 
					    name: str
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,10 @@
 | 
				
			|||||||
import sys
 | 
					import sys
 | 
				
			||||||
from typing import Sequence, TypeVar
 | 
					from typing import Any, Iterator, Sequence, TypeVar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import numpy as np
 | 
					import numpy as np
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
T = TypeVar("T")
 | 
					T = TypeVar("T")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,10 @@
 | 
				
			|||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import numpy as np
 | 
					import numpy as np
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
xyz = np.asarray(
 | 
					xyz = np.asarray(
 | 
				
			||||||
    [
 | 
					    [
 | 
				
			||||||
        tuple(int(x) for x in row.split(","))  # type: ignore
 | 
					        tuple(int(x) for x in row.split(","))  # type: ignore
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,12 @@
 | 
				
			|||||||
import sys
 | 
					import sys
 | 
				
			||||||
from typing import Any, Literal
 | 
					from typing import Any, Iterator, Literal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import numpy as np
 | 
					import numpy as np
 | 
				
			||||||
import parse  # pyright: ignore[reportMissingTypeStubs]
 | 
					import parse  # pyright: ignore[reportMissingTypeStubs]
 | 
				
			||||||
from numpy.typing import NDArray
 | 
					from numpy.typing import NDArray
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Reagent = Literal["ore", "clay", "obsidian", "geode"]
 | 
					Reagent = Literal["ore", "clay", "obsidian", "geode"]
 | 
				
			||||||
REAGENTS: tuple[Reagent, ...] = (
 | 
					REAGENTS: tuple[Reagent, ...] = (
 | 
				
			||||||
    "ore",
 | 
					    "ore",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,6 @@
 | 
				
			|||||||
import sys
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def score_1(ux: int, vx: int) -> int:
 | 
					def score_1(ux: int, vx: int) -> int:
 | 
				
			||||||
@@ -33,7 +35,9 @@ def score_2(ux: int, vx: int) -> int:
 | 
				
			|||||||
    return (ux + vx - 1) % 3 + 1 + vx * 3
 | 
					    return (ux + vx - 1) % 3 + 1 + vx * 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lines = sys.stdin.readlines()
 | 
					class Solver(BaseSolver):
 | 
				
			||||||
 | 
					    def solve(self, input: str) -> Iterator[Any]:
 | 
				
			||||||
 | 
					        lines = input.splitlines()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # the solution relies on replacing rock / paper / scissor by values 0 / 1 / 2 and using
 | 
					        # the solution relies on replacing rock / paper / scissor by values 0 / 1 / 2 and using
 | 
				
			||||||
        # modulo-3 arithmetic
 | 
					        # modulo-3 arithmetic
 | 
				
			||||||
@@ -47,7 +51,7 @@ lines = sys.stdin.readlines()
 | 
				
			|||||||
        values = [(ord(row[0]) - ord("A"), ord(row[2]) - ord("X")) for row in lines]
 | 
					        values = [(ord(row[0]) - ord("A"), ord(row[2]) - ord("X")) for row in lines]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # part 1 - 13526
 | 
					        # part 1 - 13526
 | 
				
			||||||
print(f"answer 1 is {sum(score_1(*v) for v in values)}")
 | 
					        yield sum(score_1(*v) for v in values)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # part 2 - 14204
 | 
					        # part 2 - 14204
 | 
				
			||||||
print(f"answer 2 is {sum(score_2(*v) for v in values)}")
 | 
					        yield sum(score_2(*v) for v in values)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,9 @@
 | 
				
			|||||||
from __future__ import annotations
 | 
					from __future__ import annotations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Number:
 | 
					class Number:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,8 @@
 | 
				
			|||||||
import operator
 | 
					import operator
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
from typing import Callable
 | 
					from typing import Any, Callable, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def compute(monkeys: dict[str, int | tuple[str, str, str]], monkey: str) -> int:
 | 
					def compute(monkeys: dict[str, int | tuple[str, str, str]], monkey: str) -> int:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,11 @@
 | 
				
			|||||||
import re
 | 
					import re
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
from typing import Callable
 | 
					from typing import Any, Callable, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import numpy as np
 | 
					import numpy as np
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VOID, EMPTY, WALL = 0, 1, 2
 | 
					VOID, EMPTY, WALL = 0, 1, 2
 | 
				
			||||||
TILE_FROM_CHAR = {" ": VOID, ".": EMPTY, "#": WALL}
 | 
					TILE_FROM_CHAR = {" ": VOID, ".": EMPTY, "#": WALL}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,9 @@
 | 
				
			|||||||
import itertools
 | 
					import itertools
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
from collections import defaultdict
 | 
					from collections import defaultdict
 | 
				
			||||||
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Directions = list[
 | 
					Directions = list[
 | 
				
			||||||
    tuple[
 | 
					    tuple[
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,9 @@ import heapq
 | 
				
			|||||||
import math
 | 
					import math
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
from collections import defaultdict
 | 
					from collections import defaultdict
 | 
				
			||||||
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lines = sys.stdin.read().splitlines()
 | 
					lines = sys.stdin.read().splitlines()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,7 @@
 | 
				
			|||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lines = sys.stdin.read().splitlines()
 | 
					lines = sys.stdin.read().splitlines()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,23 +1,28 @@
 | 
				
			|||||||
import string
 | 
					import string
 | 
				
			||||||
import sys
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lines = [line.strip() for line in sys.stdin.readlines()]
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Solver(BaseSolver):
 | 
				
			||||||
 | 
					    def solve(self, input: str) -> Iterator[Any]:
 | 
				
			||||||
 | 
					        lines = [line.strip() for line in input.splitlines()]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # extract content of each part
 | 
					        # extract content of each part
 | 
				
			||||||
parts = [(set(line[: len(line) // 2]), set(line[len(line) // 2 :])) for line in lines]
 | 
					        parts = [
 | 
				
			||||||
 | 
					            (set(line[: len(line) // 2]), set(line[len(line) // 2 :])) for line in lines
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # priorities
 | 
					        # priorities
 | 
				
			||||||
        priorities = {c: i + 1 for i, c in enumerate(string.ascii_letters)}
 | 
					        priorities = {c: i + 1 for i, c in enumerate(string.ascii_letters)}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # part 1
 | 
					        # part 1
 | 
				
			||||||
part1 = sum(priorities[c] for p1, p2 in parts for c in p1.intersection(p2))
 | 
					        yield sum(priorities[c] for p1, p2 in parts for c in p1.intersection(p2))
 | 
				
			||||||
print(f"answer 1 is {part1}")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # part 2
 | 
					        # part 2
 | 
				
			||||||
        n_per_group = 3
 | 
					        n_per_group = 3
 | 
				
			||||||
part2 = sum(
 | 
					        yield sum(
 | 
				
			||||||
            priorities[c]
 | 
					            priorities[c]
 | 
				
			||||||
            for i in range(0, len(lines), n_per_group)
 | 
					            for i in range(0, len(lines), n_per_group)
 | 
				
			||||||
            for c in set(lines[i]).intersection(*lines[i + 1 : i + n_per_group])
 | 
					            for c in set(lines[i]).intersection(*lines[i + 1 : i + n_per_group])
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
print(f"answer 2 is {part2}")
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
import sys
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lines = [line.strip() for line in sys.stdin.readlines()]
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def make_range(value: str) -> set[int]:
 | 
					def make_range(value: str) -> set[int]:
 | 
				
			||||||
@@ -8,10 +8,13 @@ def make_range(value: str) -> set[int]:
 | 
				
			|||||||
    return set(range(int(parts[0]), int(parts[1]) + 1))
 | 
					    return set(range(int(parts[0]), int(parts[1]) + 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sections = [tuple(make_range(part) for part in line.split(",")) for line in lines]
 | 
					class Solver(BaseSolver):
 | 
				
			||||||
 | 
					    def solve(self, input: str) -> Iterator[Any]:
 | 
				
			||||||
 | 
					        lines = [line.strip() for line in input.splitlines()]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
answer_1 = sum(s1.issubset(s2) or s2.issubset(s1) for s1, s2 in sections)
 | 
					        sections = [
 | 
				
			||||||
print(f"answer 1 is {answer_1}")
 | 
					            tuple(make_range(part) for part in line.split(",")) for line in lines
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
answer_2 = sum(bool(s1.intersection(s2)) for s1, s2 in sections)
 | 
					        yield sum(s1.issubset(s2) or s2.issubset(s1) for s1, s2 in sections)
 | 
				
			||||||
print(f"answer 1 is {answer_2}")
 | 
					        yield sum(bool(s1.intersection(s2)) for s1, s2 in sections)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,12 @@
 | 
				
			|||||||
import copy
 | 
					import copy
 | 
				
			||||||
import sys
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
blocks_s, moves_s = (part.splitlines() for part in sys.stdin.read().split("\n\n"))
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Solver(BaseSolver):
 | 
				
			||||||
 | 
					    def solve(self, input: str) -> Iterator[Any]:
 | 
				
			||||||
 | 
					        blocks_s, moves_s = (part.splitlines() for part in input.split("\n\n"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        blocks: dict[str, list[str]] = {stack: [] for stack in blocks_s[-1].split()}
 | 
					        blocks: dict[str, list[str]] = {stack: [] for stack in blocks_s[-1].split()}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -34,8 +39,5 @@ for move in moves_s:
 | 
				
			|||||||
            blocks_2[to_].extend(blocks_2[from_][-count:])
 | 
					            blocks_2[to_].extend(blocks_2[from_][-count:])
 | 
				
			||||||
            del blocks_2[from_][-count:]
 | 
					            del blocks_2[from_][-count:]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
answer_1 = "".join(s[-1] for s in blocks_1.values())
 | 
					        yield "".join(s[-1] for s in blocks_1.values())
 | 
				
			||||||
print(f"answer 1 is {answer_1}")
 | 
					        yield "".join(s[-1] for s in blocks_2.values())
 | 
				
			||||||
 | 
					 | 
				
			||||||
answer_2 = "".join(s[-1] for s in blocks_2.values())
 | 
					 | 
				
			||||||
print(f"answer 2 is {answer_2}")
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,6 @@
 | 
				
			|||||||
import sys
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def index_of_first_n_differents(data: str, n: int) -> int:
 | 
					def index_of_first_n_differents(data: str, n: int) -> int:
 | 
				
			||||||
@@ -8,8 +10,7 @@ def index_of_first_n_differents(data: str, n: int) -> int:
 | 
				
			|||||||
    return -1
 | 
					    return -1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
data = sys.stdin.read().strip()
 | 
					class Solver(BaseSolver):
 | 
				
			||||||
 | 
					    def solve(self, input: str) -> Iterator[Any]:
 | 
				
			||||||
 | 
					        yield index_of_first_n_differents(input, 4)
 | 
				
			||||||
print(f"answer 1 is {index_of_first_n_differents(data, 4)}")
 | 
					        yield index_of_first_n_differents(input, 14)
 | 
				
			||||||
print(f"answer 2 is {index_of_first_n_differents(data, 14)}")
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,12 @@
 | 
				
			|||||||
import sys
 | 
					 | 
				
			||||||
from pathlib import Path
 | 
					from pathlib import Path
 | 
				
			||||||
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lines = sys.stdin.read().splitlines()
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Solver(BaseSolver):
 | 
				
			||||||
 | 
					    def solve(self, input: str) -> Iterator[Any]:
 | 
				
			||||||
 | 
					        lines = [line.strip() for line in input.splitlines()]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # we are going to use Path to create path and go up/down in the file tree since it
 | 
					        # we are going to use Path to create path and go up/down in the file tree since it
 | 
				
			||||||
        # implements everything we need
 | 
					        # implements everything we need
 | 
				
			||||||
@@ -53,7 +58,6 @@ for line in lines[1:]:
 | 
				
			|||||||
                trees[cur_path].append(path)
 | 
					                trees[cur_path].append(path)
 | 
				
			||||||
                sizes[path] = size
 | 
					                sizes[path] = size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
        def compute_size(path: Path) -> int:
 | 
					        def compute_size(path: Path) -> int:
 | 
				
			||||||
            size = sizes[path]
 | 
					            size = sizes[path]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -62,12 +66,10 @@ def compute_size(path: Path) -> int:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            return sum(compute_size(sub) for sub in trees[path])
 | 
					            return sum(compute_size(sub) for sub in trees[path])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
        acc_sizes = {path: compute_size(path) for path in trees}
 | 
					        acc_sizes = {path: compute_size(path) for path in trees}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # part 1
 | 
					        # part 1
 | 
				
			||||||
answer_1 = sum(size for size in acc_sizes.values() if size <= 100_000)
 | 
					        yield sum(size for size in acc_sizes.values() if size <= 100_000)
 | 
				
			||||||
print(f"answer 1 is {answer_1}")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # part 2
 | 
					        # part 2
 | 
				
			||||||
        total_space = 70_000_000
 | 
					        total_space = 70_000_000
 | 
				
			||||||
@@ -76,5 +78,4 @@ free_space = total_space - acc_sizes[base_path]
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        to_free_space = update_space - free_space
 | 
					        to_free_space = update_space - free_space
 | 
				
			||||||
 | 
					
 | 
				
			||||||
answer_2 = min(size for size in acc_sizes.values() if size >= to_free_space)
 | 
					        yield min(size for size in acc_sizes.values() if size >= to_free_space)
 | 
				
			||||||
print(f"answer 2 is {answer_2}")
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,14 @@
 | 
				
			|||||||
import sys
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import numpy as np
 | 
					import numpy as np
 | 
				
			||||||
from numpy.typing import NDArray
 | 
					from numpy.typing import NDArray
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lines = sys.stdin.read().splitlines()
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Solver(BaseSolver):
 | 
				
			||||||
 | 
					    def solve(self, input: str) -> Iterator[Any]:
 | 
				
			||||||
 | 
					        lines = [line.strip() for line in input.splitlines()]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        trees = np.array([[int(x) for x in row] for row in lines])
 | 
					        trees = np.array([[int(x) for x in row] for row in lines])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -22,9 +27,7 @@ highest_trees[1:-1, 1:-1] = [
 | 
				
			|||||||
            for i in range(1, trees.shape[0] - 1)
 | 
					            for i in range(1, trees.shape[0] - 1)
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
answer_1 = (highest_trees.min(axis=2) < trees).sum()
 | 
					        yield (highest_trees.min(axis=2) < trees).sum()
 | 
				
			||||||
print(f"answer 1 is {answer_1}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def viewing_distance(row_of_trees: NDArray[np.int_], value: int) -> int:
 | 
					        def viewing_distance(row_of_trees: NDArray[np.int_], value: int) -> int:
 | 
				
			||||||
            w = np.where(row_of_trees >= value)[0]
 | 
					            w = np.where(row_of_trees >= value)[0]
 | 
				
			||||||
@@ -34,7 +37,6 @@ def viewing_distance(row_of_trees: NDArray[np.int_], value: int) -> int:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            return w[0] + 1
 | 
					            return w[0] + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
        # answer 2
 | 
					        # answer 2
 | 
				
			||||||
        v_distances = np.zeros(trees.shape + (4,), dtype=int)
 | 
					        v_distances = np.zeros(trees.shape + (4,), dtype=int)
 | 
				
			||||||
        v_distances[1:-1, 1:-1, :] = [
 | 
					        v_distances[1:-1, 1:-1, :] = [
 | 
				
			||||||
@@ -49,5 +51,4 @@ v_distances[1:-1, 1:-1, :] = [
 | 
				
			|||||||
            ]
 | 
					            ]
 | 
				
			||||||
            for i in range(1, trees.shape[0] - 1)
 | 
					            for i in range(1, trees.shape[0] - 1)
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
answer_2 = np.prod(v_distances, axis=2).max()
 | 
					        yield np.prod(v_distances, axis=2).max()
 | 
				
			||||||
print(f"answer 2 is {answer_2}")
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,10 @@
 | 
				
			|||||||
import sys
 | 
					import itertools as it
 | 
				
			||||||
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import numpy as np
 | 
					import numpy as np
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import BaseSolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def move(head: tuple[int, int], command: str) -> tuple[int, int]:
 | 
					def move(head: tuple[int, int], command: str) -> tuple[int, int]:
 | 
				
			||||||
    h_col, h_row = head
 | 
					    h_col, h_row = head
 | 
				
			||||||
@@ -43,17 +46,14 @@ def run(commands: list[str], n_blocks: int) -> list[tuple[int, int]]:
 | 
				
			|||||||
    return visited
 | 
					    return visited
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lines = sys.stdin.read().splitlines()
 | 
					class Solver(BaseSolver):
 | 
				
			||||||
 | 
					    def solve(self, input: str) -> Iterator[Any]:
 | 
				
			||||||
 | 
					        lines = [line.strip() for line in input.splitlines()]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # flatten the commands
 | 
					        # flatten the commands
 | 
				
			||||||
commands: list[str] = []
 | 
					        commands = list(
 | 
				
			||||||
for line in lines:
 | 
					            it.chain(*(p[0] * int(p[1]) for line in lines if (p := line.split())))
 | 
				
			||||||
    d, c = line.split()
 | 
					        )
 | 
				
			||||||
    commands.extend(d * int(c))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        yield len(set(run(commands, n_blocks=2)))
 | 
				
			||||||
visited_1 = run(commands, n_blocks=2)
 | 
					        yield len(set(run(commands, n_blocks=10)))
 | 
				
			||||||
print(f"answer 1 is {len(set(visited_1))}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
visited_2 = run(commands, n_blocks=10)
 | 
					 | 
				
			||||||
print(f"answer 2 is {len(set(visited_2))}")
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					# pyright: reportUnknownMemberType=false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from typing import Any, Iterator
 | 
					from typing import Any, Iterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import networkx as nx
 | 
					import networkx as nx
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user