Compare commits

..

1 Commits

Author SHA1 Message Date
Mikael CAPELLE
40ab70271e 2023 day 17, v2. 2023-12-19 14:26:16 +01:00
400 changed files with 234 additions and 14078 deletions

View File

@ -1,12 +0,0 @@
---
kind: pipeline
type: docker
name: default
steps:
- name: tests
image: python:3.10-slim
commands:
- pip install poetry
- poetry install
- poetry run poe lint

5
.gitignore vendored
View File

@ -1,6 +1 @@
# python / VS Code
venv venv
__pycache__
.ruff_cache
.vscode
build

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,13 +1,12 @@
import sys import sys
from math import prod from math import prod
from typing import Literal, TypeAlias, cast from typing import Literal, cast
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()
Command: TypeAlias = Literal["forward", "up", "down"] commands = [
(cast(Literal["forward", "up", "down"], (p := line.split())[0]), int(p[1]))
commands: list[tuple[Command, int]] = [ for line in lines
(cast(Command, (p := line.split())[0]), int(p[1])) for line in lines
] ]

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

View File

@ -1,4 +1,6 @@
import sys import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines() lines = sys.stdin.read().splitlines()

21
2021/day7.py Normal file
View File

@ -0,0 +1,21 @@
import sys
import numpy as np
positions = np.asarray([int(c) for c in sys.stdin.read().strip().split(",")])
min_position, max_position = positions.min(), positions.max()
# part 1
answer_1 = min(
np.sum(np.abs(positions - position))
for position in range(min_position, max_position + 1)
)
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = min(
np.sum(abs(positions - position) * (abs(positions - position) + 1) // 2)
for position in range(min_position, max_position + 1)
)
print(f"answer 2 is {answer_2}")

13
2021/day9.py Normal file
View File

@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

View File

@ -122,8 +122,8 @@ lines = sys.stdin.read().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]
start: tuple[int, int] | None = None start: tuple[int, int]
end: tuple[int, int] | None = None end: tuple[int, int]
# for part 2 # for part 2
start_s: list[tuple[int, int]] = [] start_s: list[tuple[int, int]] = []
@ -138,9 +138,6 @@ for i_row, row in enumerate(grid):
elif col == 0: elif col == 0:
start_s.append((i_row, i_col)) start_s.append((i_row, i_col))
assert start is not None
assert end is not None
# fix values # fix values
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")

View File

@ -1,22 +1,20 @@
import sys import sys
from typing import Any
import numpy as np import numpy as np
import parse # type: ignore import parse
from numpy.typing import NDArray
def part1(sensor_to_beacon: dict[tuple[int, int], tuple[int, int]], row: int) -> int: def part1(sensor_to_beacon: dict[tuple[int, int], tuple[int, int]], row: int) -> int:
no_beacons_row_l: list[NDArray[np.floating[Any]]] = [] no_beacons_row_l: list[np.ndarray] = []
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) # closest d = abs(sx - bx) + abs(sy - by) # closest
no_beacons_row_l.append(sx - np.arange(0, d - abs(sy - row) + 1)) # type: ignore no_beacons_row_l.append(sx - np.arange(0, d - abs(sy - row) + 1))
no_beacons_row_l.append(sx + np.arange(0, d - abs(sy - row) + 1)) # type: ignore no_beacons_row_l.append(sx + np.arange(0, d - abs(sy - row) + 1))
beacons_at_row = set(bx for (bx, by) in sensor_to_beacon.values() if by == row) beacons_at_row = set(bx for (bx, by) in sensor_to_beacon.values() if by == row)
no_beacons_row = set(np.concatenate(no_beacons_row_l)).difference(beacons_at_row) # type: ignore no_beacons_row = set(np.concatenate(no_beacons_row_l)).difference(beacons_at_row)
return len(no_beacons_row) return len(no_beacons_row)
@ -58,12 +56,11 @@ def part2_cplex(
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.abs(x - sx) + m.abs(y - sy) >= d + 1, ctname=f"ct_{sx}_{sy}") # type: ignore m.add_constraint(m.abs(x - sx) + m.abs(y - sy) >= d + 1, ctname=f"ct_{sx}_{sy}")
m.set_objective("min", x + y) m.set_objective("min", x + y)
s = m.solve() s = m.solve()
assert s is not None
vx = int(s.get_value(x)) vx = int(s.get_value(x))
vy = int(s.get_value(y)) vy = int(s.get_value(y))
@ -75,7 +72,7 @@ lines = sys.stdin.read().splitlines()
sensor_to_beacon: dict[tuple[int, int], tuple[int, int]] = {} sensor_to_beacon: dict[tuple[int, int], tuple[int, int]] = {}
for line in lines: for line in lines:
r: dict[str, str] = parse.parse( # type: ignore r = parse.parse(
"Sensor at x={sx}, y={sy}: closest beacon is at x={bx}, y={by}", line "Sensor at x={sx}, y={sy}: closest beacon is at x={bx}, y={by}", line
) )
sensor_to_beacon[int(r["sx"]), int(r["sy"])] = (int(r["bx"]), int(r["by"])) sensor_to_beacon[int(r["sx"]), int(r["sy"])] = (int(r["bx"]), int(r["by"]))

View File

@ -1,4 +1,5 @@
import sys import sys
from typing import FrozenSet
import numpy as np import numpy as np

View File

@ -1,9 +1,9 @@
import sys import sys
from typing import Any, Literal from typing import Literal
import numpy as np import numpy as np
import parse # pyright: ignore[reportMissingTypeStubs] import parse
from numpy.typing import NDArray from tqdm import tqdm
Reagent = Literal["ore", "clay", "obsidian", "geode"] Reagent = Literal["ore", "clay", "obsidian", "geode"]
REAGENTS: tuple[Reagent, ...] = ( REAGENTS: tuple[Reagent, ...] = (
@ -35,7 +35,7 @@ class State:
self.robots = robots self.robots = robots
self.reagents = reagents self.reagents = reagents
def __eq__(self, other: object) -> bool: def __eq__(self, other) -> bool:
return ( return (
isinstance(other, State) isinstance(other, State)
and self.robots == other.robots and self.robots == other.robots
@ -66,7 +66,7 @@ lines = sys.stdin.read().splitlines()
blueprints: list[dict[Reagent, IntOfReagent]] = [] blueprints: list[dict[Reagent, IntOfReagent]] = []
for line in lines: for line in lines:
r: list[int] = parse.parse( # type: ignore r = parse.parse(
"Blueprint {}: " "Blueprint {}: "
"Each ore robot costs {:d} ore. " "Each ore robot costs {:d} ore. "
"Each clay robot costs {:d} ore. " "Each clay robot costs {:d} ore. "
@ -94,12 +94,11 @@ def run(blueprint: dict[Reagent, dict[Reagent, int]], max_time: int) -> int:
name: max(blueprint[r].get(name, 0) for r in REAGENTS) for name in REAGENTS name: max(blueprint[r].get(name, 0) for r in REAGENTS) for name in REAGENTS
} }
state_after_t: dict[int, set[State]] = {0: {State()}} state_after_t: dict[int, set[State]] = {0: [State()]}
for t in range(1, max_time + 1): for t in range(1, max_time + 1):
# list of new states at the end of step t that we are going to prune later # list of new states at the end of step t that we are going to prune later
states_for_t: set[State] = set() states_for_t: set[State] = set()
robots_that_can_be_built: list[Reagent]
for state in state_after_t[t - 1]: for state in state_after_t[t - 1]:
robots_that_can_be_built = [ robots_that_can_be_built = [
@ -133,7 +132,7 @@ def run(blueprint: dict[Reagent, dict[Reagent, int]], max_time: int) -> int:
for robot in robots_that_can_be_built: for robot in robots_that_can_be_built:
robots = state.robots.copy() robots = state.robots.copy()
robots[robot] += 1 robots[robot] += 1
reagents: IntOfReagent = { reagents = {
reagent: state.reagents[reagent] reagent: state.reagents[reagent]
+ state.robots[reagent] + state.robots[reagent]
- blueprint[robot].get(reagent, 0) - blueprint[robot].get(reagent, 0)
@ -152,7 +151,7 @@ def run(blueprint: dict[Reagent, dict[Reagent, int]], max_time: int) -> int:
] ]
) )
to_keep: list[NDArray[np.integer[Any]]] = [] to_keep = []
while len(np_states) > 0: while len(np_states) > 0:
first_dom = (np_states[1:] >= np_states[0]).all(axis=1).any() first_dom = (np_states[1:] >= np_states[0]).all(axis=1).any()

Some files were not shown because too many files have changed in this diff Show More