Start fixing 2022 for new API.
This commit is contained in:
parent
377e501d34
commit
6fd569aeba
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user