It kinda works
This commit is contained in:
parent
a0e7c8c7f9
commit
fbac277c8a
4 changed files with 124 additions and 0 deletions
1
challenges/2023/17-clumsyCrucible/README.md
Normal file
1
challenges/2023/17-clumsyCrucible/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
# [Day 17: Clumsy Crucible](https://adventofcode.com/2023/day/17)
|
83
challenges/2023/17-clumsyCrucible/main.py
Normal file
83
challenges/2023/17-clumsyCrucible/main.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
import sys
|
||||
import gridutil.grid as gu
|
||||
import gridutil.coord as cu
|
||||
|
||||
|
||||
def parse(instr: str) -> gu.Grid:
|
||||
g = gu.parse(instr)
|
||||
return {k: int(g[k]) for k in g}
|
||||
|
||||
|
||||
def get_shortest_path(grid: gu.Grid, start: cu.Coordinate, end: cu.Coordinate) -> list[cu.Coordinate]:
|
||||
d = {start: (0, 0, cu.Direction.Right)}
|
||||
p = {}
|
||||
f = {}
|
||||
|
||||
while end not in d:
|
||||
w = min(filter(lambda x: x[0] not in f, d.items()), key=lambda x: x[1][0])[0]
|
||||
f[w] = None
|
||||
|
||||
dist_w, prev_steps, prev_direction = d[w]
|
||||
|
||||
for direction in cu.Direction:
|
||||
if (direction == prev_direction and prev_steps == 3) or direction == prev_direction.opposite():
|
||||
continue
|
||||
u = cu.add(w, direction.delta())
|
||||
if u not in grid:
|
||||
continue
|
||||
|
||||
if u not in d or dist_w + grid[u] < d[u][0]:
|
||||
d[u] = (dist_w + grid[u], prev_steps + 1 if direction == prev_direction else 1, direction)
|
||||
p[u] = w
|
||||
|
||||
if u == end:
|
||||
break
|
||||
|
||||
# raise SystemExit(14)
|
||||
|
||||
res = [end]
|
||||
cursor = p[end]
|
||||
while cursor != start:
|
||||
res.append(cursor)
|
||||
cursor = p[cursor]
|
||||
return list(reversed(res))
|
||||
|
||||
|
||||
def one(instr: str):
|
||||
grid = parse(instr)
|
||||
end = (gu.get_max_x(grid), gu.get_max_y(grid))
|
||||
path = get_shortest_path(grid, (0, 0), end)
|
||||
|
||||
gu.print_grid(grid, file=sys.stderr)
|
||||
_debug()
|
||||
|
||||
g = grid.copy()
|
||||
for p in path:
|
||||
g[p] = "█"
|
||||
|
||||
gu.print_grid(g, file=sys.stderr)
|
||||
|
||||
acc = 0
|
||||
for node in path:
|
||||
acc += grid[node]
|
||||
return acc
|
||||
|
||||
|
||||
def two(instr: str):
|
||||
return
|
||||
|
||||
|
||||
def _debug(*args, **kwargs):
|
||||
kwargs["file"] = sys.stderr
|
||||
print(*args, **kwargs)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2 or sys.argv[1] not in ["1", "2"]:
|
||||
print("Missing day argument", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
inp = sys.stdin.read().strip()
|
||||
if sys.argv[1] == "1":
|
||||
print(one(inp))
|
||||
else:
|
||||
print(two(inp))
|
8
challenges/2023/17-clumsyCrucible/tests.json
Normal file
8
challenges/2023/17-clumsyCrucible/tests.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"1": [
|
||||
{
|
||||
"is": "102",
|
||||
"input": "2413432311323\n3215453535623\n3255245654254\n3446585845452\n4546657867536\n1438598798454\n4457876987766\n3637877979653\n4654967986887\n4564679986453\n1224686865563\n2546548887735\n4322674655533\n\n"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
from enum import Enum, auto
|
||||
|
||||
|
||||
Coordinate = tuple[int, int]
|
||||
|
||||
|
||||
|
@ -11,3 +14,32 @@ def sub(a: Coordinate, b: Coordinate) -> Coordinate:
|
|||
xa, ya = a
|
||||
xb, yb = b
|
||||
return xa - xb, ya - yb
|
||||
|
||||
|
||||
class Direction(Enum):
|
||||
Up = auto()
|
||||
Down = auto()
|
||||
Left = auto()
|
||||
Right = auto()
|
||||
|
||||
def delta(self) -> Coordinate:
|
||||
match self:
|
||||
case Direction.Up:
|
||||
return (0, -1)
|
||||
case Direction.Down:
|
||||
return (0, 1)
|
||||
case Direction.Left:
|
||||
return (-1, 0)
|
||||
case Direction.Right:
|
||||
return (1, 0)
|
||||
|
||||
def opposite(self):
|
||||
match self:
|
||||
case Direction.Down:
|
||||
return Direction.Up
|
||||
case Direction.Up:
|
||||
return Direction.Down
|
||||
case Direction.Left:
|
||||
return Direction.Right
|
||||
case Direction.Right:
|
||||
return Direction.Left
|
Loading…
Add table
Add a link
Reference in a new issue