Refactor code for API (#3)
Co-authored-by: Mikael CAPELLE <mikael.capelle@thalesaleniaspace.com> Co-authored-by: Mikaël Capelle <capelle.mikael@gmail.com> Reviewed-on: #3
This commit is contained in:
@@ -1,14 +1,17 @@
|
||||
import sys
|
||||
from collections import Counter
|
||||
from typing import Any, Iterator
|
||||
|
||||
values = list(map(int, sys.stdin.read().strip().split()))
|
||||
from ..base import BaseSolver
|
||||
|
||||
column_1 = sorted(values[::2])
|
||||
column_2 = sorted(values[1::2])
|
||||
counter_2 = Counter(column_2)
|
||||
|
||||
answer_1 = sum(abs(v1 - v2) for v1, v2 in zip(column_1, column_2, strict=True))
|
||||
answer_2 = sum(value * counter_2.get(value, 0) for value in column_1)
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]:
|
||||
values = list(map(int, input.split()))
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
column_1 = sorted(values[::2])
|
||||
column_2 = sorted(values[1::2])
|
||||
|
||||
yield sum(abs(v1 - v2) for v1, v2 in zip(column_1, column_2, strict=True))
|
||||
|
||||
counter_2 = Counter(column_2)
|
||||
yield sum(value * counter_2.get(value, 0) for value in column_1)
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,22 +1,23 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
from ..base import BaseSolver
|
||||
|
||||
|
||||
def is_safe(level: list[int]) -> bool:
|
||||
diff = [a - b for a, b in zip(level[:-1], level[1:], strict=True)]
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]:
|
||||
def is_safe(level: list[int]) -> bool:
|
||||
diff = [a - b for a, b in zip(level[:-1], level[1:], strict=True)]
|
||||
|
||||
return sum(d > 0 for d in diff) in (0, len(diff)) and all(
|
||||
1 <= abs(d) <= 3 for d in diff
|
||||
)
|
||||
return sum(d > 0 for d in diff) in (0, len(diff)) and all(
|
||||
1 <= abs(d) <= 3 for d in diff
|
||||
)
|
||||
|
||||
def is_any_safe(level: list[int]) -> bool:
|
||||
return any(
|
||||
is_safe(level[:i] + level[i + 1 :]) for i in range(0, len(level))
|
||||
)
|
||||
|
||||
def is_any_safe(level: list[int]) -> bool:
|
||||
return any(is_safe(level[:i] + level[i + 1 :]) for i in range(0, len(level)))
|
||||
levels = [[int(c) for c in r.split()] for r in input.splitlines()]
|
||||
|
||||
|
||||
levels = [[int(c) for c in r.split()] for r in sys.stdin.read().strip().splitlines()]
|
||||
|
||||
answer_1 = sum(is_safe(level) for level in levels)
|
||||
answer_2 = sum(is_safe(level) or is_any_safe(level) for level in levels)
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
yield sum(is_safe(level) for level in levels)
|
||||
yield sum(is_safe(level) or is_any_safe(level) for level in levels)
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
@@ -1,34 +1,30 @@
|
||||
import re
|
||||
import sys
|
||||
from typing import Iterator
|
||||
from typing import Any, Iterator
|
||||
|
||||
from ..base import BaseSolver
|
||||
|
||||
|
||||
def extract_multiply(line: str) -> Iterator[int]:
|
||||
for m in re.finditer(r"mul\(([0-9]{1,3}),\s*([0-9]{1,3})\)", line):
|
||||
yield int(m.group(1)) * int(m.group(2))
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]:
|
||||
def extract_multiply(line: str) -> Iterator[int]:
|
||||
for m in re.finditer(r"mul\(([0-9]{1,3}),\s*([0-9]{1,3})\)", line):
|
||||
yield int(m.group(1)) * int(m.group(2))
|
||||
|
||||
def valid_memory_blocks(line: str) -> Iterator[str]:
|
||||
accumulate = True
|
||||
while line:
|
||||
if accumulate:
|
||||
if (dont_i := line.find("don't()")) != -1:
|
||||
yield line[:dont_i]
|
||||
line, accumulate = line[dont_i:], False
|
||||
else:
|
||||
yield line
|
||||
line = ""
|
||||
else:
|
||||
if (do_i := line.find("do()")) != -1:
|
||||
line, accumulate = line[do_i:], True
|
||||
else:
|
||||
line = ""
|
||||
|
||||
def valid_memory_blocks(line: str) -> Iterator[str]:
|
||||
accumulate = True
|
||||
while line:
|
||||
if accumulate:
|
||||
if (dont_i := line.find("don't()")) != -1:
|
||||
yield line[:dont_i]
|
||||
line, accumulate = line[dont_i:], False
|
||||
else:
|
||||
yield line
|
||||
line = ""
|
||||
else:
|
||||
if (do_i := line.find("do()")) != -1:
|
||||
line, accumulate = line[do_i:], True
|
||||
else:
|
||||
line = ""
|
||||
|
||||
|
||||
line = sys.stdin.read().strip()
|
||||
|
||||
answer_1 = sum(extract_multiply(line))
|
||||
answer_2 = sum(sum(extract_multiply(block)) for block in valid_memory_blocks(line))
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
yield sum(extract_multiply(input))
|
||||
yield sum(sum(extract_multiply(block)) for block in valid_memory_blocks(input))
|
||||
|
@@ -1,31 +1,37 @@
|
||||
import itertools as it
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().strip().splitlines()
|
||||
n = len(lines)
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = sum(
|
||||
line.count("XMAS") + line.count("SAMX")
|
||||
for i in range(n)
|
||||
for ri, rk, ro, ci, ck, cm in (
|
||||
(1, 0, 0, 0, 1, n),
|
||||
(0, 1, 0, 1, 0, n),
|
||||
(0, 1, 0, 1, 1, n - i),
|
||||
(0, -1, -1, 1, 1, n - i),
|
||||
(1, 1, 0, 0, 1, n - i if i != 0 else 0),
|
||||
(-1, -1, -1, 0, 1, n - i if i != 0 else 0),
|
||||
)
|
||||
if (
|
||||
line := "".join(lines[ri * i + rk * k + ro][ci * i + ck * k] for k in range(cm))
|
||||
)
|
||||
)
|
||||
|
||||
answer_2 = sum(
|
||||
lines[i][j] == "A"
|
||||
and "".join(lines[i + di][j + dj] for di, dj in it.product((-1, 1), (-1, 1)))
|
||||
in {"MSMS", "SSMM", "MMSS", "SMSM"}
|
||||
for i, j in it.product(range(1, n - 1), range(1, n - 1))
|
||||
)
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]:
|
||||
lines = input.splitlines()
|
||||
n = len(lines)
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
yield sum(
|
||||
line.count("XMAS") + line.count("SAMX")
|
||||
for i in range(n)
|
||||
for ri, rk, ro, ci, ck, cm in (
|
||||
(1, 0, 0, 0, 1, n),
|
||||
(0, 1, 0, 1, 0, n),
|
||||
(0, 1, 0, 1, 1, n - i),
|
||||
(0, -1, -1, 1, 1, n - i),
|
||||
(1, 1, 0, 0, 1, n - i if i != 0 else 0),
|
||||
(-1, -1, -1, 0, 1, n - i if i != 0 else 0),
|
||||
)
|
||||
if (
|
||||
line := "".join(
|
||||
lines[ri * i + rk * k + ro][ci * i + ck * k] for k in range(cm)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
yield sum(
|
||||
lines[i][j] == "A"
|
||||
and "".join(
|
||||
lines[i + di][j + dj] for di, dj in it.product((-1, 1), (-1, 1))
|
||||
)
|
||||
in {"MSMS", "SSMM", "MMSS", "SMSM"}
|
||||
for i, j in it.product(range(1, n - 1), range(1, n - 1))
|
||||
)
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from typing import Any, Iterator
|
||||
|
||||
from ..base import BaseSolver
|
||||
|
||||
|
||||
def in_correct_order(update: list[int], requirements: dict[int, set[int]]) -> bool:
|
||||
@@ -39,26 +41,25 @@ def to_correct_order(
|
||||
return update
|
||||
|
||||
|
||||
part1, part2 = sys.stdin.read().strip().split("\n\n")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]:
|
||||
part1, part2 = input.split("\n\n")
|
||||
|
||||
requirements: dict[int, set[int]] = defaultdict(set)
|
||||
for line in part1.splitlines():
|
||||
v1, v2 = line.split("|")
|
||||
requirements[int(v2)].add(int(v1))
|
||||
requirements: dict[int, set[int]] = defaultdict(set)
|
||||
for line in part1.splitlines():
|
||||
v1, v2 = line.split("|")
|
||||
requirements[int(v2)].add(int(v1))
|
||||
|
||||
updates = [list(map(int, line.split(","))) for line in part2.splitlines()]
|
||||
updates = [list(map(int, line.split(","))) for line in part2.splitlines()]
|
||||
|
||||
answer_1 = sum(
|
||||
update[len(update) // 2]
|
||||
for update in updates
|
||||
if in_correct_order(update, requirements)
|
||||
)
|
||||
yield sum(
|
||||
update[len(update) // 2]
|
||||
for update in updates
|
||||
if in_correct_order(update, requirements)
|
||||
)
|
||||
|
||||
answer_2 = sum(
|
||||
to_correct_order(update, requirements, len(update) // 2 + 1)[-1]
|
||||
for update in updates
|
||||
if not in_correct_order(update, requirements)
|
||||
)
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
yield sum(
|
||||
to_correct_order(update, requirements, len(update) // 2 + 1)[-1]
|
||||
for update in updates
|
||||
if not in_correct_order(update, requirements)
|
||||
)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import itertools as it
|
||||
import sys
|
||||
from typing import TypeAlias
|
||||
from typing import Any, Iterator, TypeAlias
|
||||
|
||||
from ..base import BaseSolver
|
||||
|
||||
NodeType: TypeAlias = tuple[tuple[int, int], tuple[int, int]]
|
||||
EdgesType: TypeAlias = dict[NodeType, tuple[NodeType, set[tuple[int, int]]]]
|
||||
@@ -91,44 +92,31 @@ def is_loop(lines: list[str], edges: EdgesType, position: tuple[int, int]):
|
||||
return current_node in found
|
||||
|
||||
|
||||
def print_grid(
|
||||
lines: list[str], marked: set[tuple[int, int]], current_pos: tuple[int, int] | None
|
||||
):
|
||||
chars = list(map(list, lines))
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]:
|
||||
# read lines
|
||||
lines = input.splitlines()
|
||||
|
||||
for i, j in marked:
|
||||
chars[i][j] = "X"
|
||||
# find and delete original position
|
||||
start_pos = next(
|
||||
(i, j)
|
||||
for i, row in enumerate(lines)
|
||||
for j, col in enumerate(row)
|
||||
if col == "^"
|
||||
)
|
||||
lines[start_pos[0]] = lines[start_pos[0]].replace("^", ".")
|
||||
|
||||
if current_pos:
|
||||
chars[current_pos[0]][current_pos[1]] = "T"
|
||||
# compute edges from the map
|
||||
edges = compute_graph(lines, (start_pos, (-1, 0)))
|
||||
|
||||
for line in chars:
|
||||
print("".join(line))
|
||||
print()
|
||||
# part 1
|
||||
marked: set[tuple[int, int]] = set()
|
||||
current_node = START_NODE
|
||||
|
||||
while current_node[0] != FINAL_POS:
|
||||
current_node, current_marked = edges[current_node]
|
||||
marked = marked.union(current_marked)
|
||||
|
||||
# read lines
|
||||
lines = sys.stdin.read().splitlines()
|
||||
yield len(marked)
|
||||
|
||||
# find and delete original position
|
||||
start_pos = next(
|
||||
(i, j) for i, row in enumerate(lines) for j, col in enumerate(row) if col == "^"
|
||||
)
|
||||
lines[start_pos[0]] = lines[start_pos[0]].replace("^", ".")
|
||||
|
||||
# compute edges from the map
|
||||
edges = compute_graph(lines, (start_pos, (-1, 0)))
|
||||
|
||||
# part 1
|
||||
marked: set[tuple[int, int]] = set()
|
||||
current_node = START_NODE
|
||||
|
||||
while current_node[0] != FINAL_POS:
|
||||
current_node, current_marked = edges[current_node]
|
||||
marked = marked.union(current_marked)
|
||||
|
||||
answer_1 = len(marked)
|
||||
print(f"answer 1 is {answer_1}")
|
||||
|
||||
answer_2 = sum(is_loop(lines, edges, pos) for pos in marked if pos != start_pos)
|
||||
print(f"answer 2 is {answer_2}")
|
||||
yield sum(is_loop(lines, edges, pos) for pos in marked if pos != start_pos)
|
||||
|
@@ -1,10 +1,50 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
def evaluate(
|
||||
target: int, numbers: list[int], concatenate: bool = False, current: int = 0
|
||||
) -> bool:
|
||||
if not numbers:
|
||||
return current == target
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
if current > target:
|
||||
return False
|
||||
|
||||
head, *tail = numbers
|
||||
|
||||
if evaluate(target, tail, concatenate, current + head) or evaluate(
|
||||
target, tail, concatenate, current * head
|
||||
):
|
||||
return True
|
||||
|
||||
if not concatenate:
|
||||
return False
|
||||
|
||||
return evaluate(target, tail, concatenate, int(str(current) + str(head)))
|
||||
|
||||
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]:
|
||||
targets = {
|
||||
int(part[0]): list(map(int, part[1].strip().split()))
|
||||
for line in input.splitlines()
|
||||
if (part := line.split(":"))
|
||||
}
|
||||
|
||||
yield sum(
|
||||
target
|
||||
for target, numbers in self.progress.wrap(
|
||||
targets.items(), total=len(targets)
|
||||
)
|
||||
if evaluate(target, numbers)
|
||||
)
|
||||
|
||||
yield sum(
|
||||
target
|
||||
for target, numbers in self.progress.wrap(
|
||||
targets.items(), total=len(targets)
|
||||
)
|
||||
if evaluate(target, numbers, True)
|
||||
)
|
||||
|
@@ -1,10 +1,76 @@
|
||||
import sys
|
||||
import itertools as it
|
||||
from collections import defaultdict
|
||||
from typing import Any, Iterator, cast
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
def compute_antinodes(
|
||||
a1: tuple[int, int],
|
||||
a2: tuple[int, int],
|
||||
n_rows: int,
|
||||
n_cols: int,
|
||||
min_distance: int = 1,
|
||||
max_distance: int | None = 1,
|
||||
):
|
||||
if a1[0] > a2[0]:
|
||||
a1, a2 = a2, a1
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
d_row, d_col = a2[0] - a1[0], a2[1] - a1[1]
|
||||
|
||||
points: list[tuple[int, int]] = []
|
||||
|
||||
for c in range(min_distance, (max_distance or n_rows) + 1):
|
||||
row_1, col_1 = a1[0] - c * d_row, a1[1] - c * d_col
|
||||
row_2, col_2 = a2[0] + c * d_row, a2[1] + c * d_col
|
||||
|
||||
valid_1, valid_2 = (
|
||||
0 <= row_1 < n_rows and 0 <= col_1 < n_cols,
|
||||
0 <= row_2 < n_rows and 0 <= col_2 < n_cols,
|
||||
)
|
||||
|
||||
if not valid_1 and not valid_2:
|
||||
break
|
||||
|
||||
if valid_1:
|
||||
points.append((row_1, col_1))
|
||||
if valid_2:
|
||||
points.append((row_2, col_2))
|
||||
|
||||
return tuple(points)
|
||||
|
||||
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]:
|
||||
lines = input.splitlines()
|
||||
|
||||
n_rows, n_cols = len(lines), len(lines[0])
|
||||
|
||||
antennas: dict[str, list[tuple[int, int]]] = defaultdict(list)
|
||||
for i, j in it.product(range(n_rows), range(n_cols)):
|
||||
if lines[i][j] != ".":
|
||||
antennas[lines[i][j]].append((i, j))
|
||||
|
||||
yield len(
|
||||
cast(set[tuple[int, int]], set()).union(
|
||||
it.chain(
|
||||
*(
|
||||
compute_antinodes(a1, a2, n_rows, n_cols)
|
||||
for antennas_of_frequency in antennas.values()
|
||||
for a1, a2 in it.permutations(antennas_of_frequency, 2)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
yield len(
|
||||
cast(set[tuple[int, int]], set()).union(
|
||||
it.chain(
|
||||
*(
|
||||
compute_antinodes(a1, a2, n_rows, n_cols, 0, None)
|
||||
for antennas_of_frequency in antennas.values()
|
||||
for a1, a2 in it.permutations(antennas_of_frequency, 2)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import sys
|
||||
from typing import Any, Iterator
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
from ..base import BaseSolver
|
||||
|
||||
answer_1 = ...
|
||||
|
||||
answer_2 = ...
|
||||
|
||||
print(f"answer 1 is {answer_1}")
|
||||
print(f"answer 2 is {answer_2}")
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
|
Reference in New Issue
Block a user