Skip to content

Commit

Permalink
day23: part2
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-ong committed Dec 23, 2023
1 parent 6c0337a commit 4992ffb
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 20 deletions.
6 changes: 3 additions & 3 deletions day23/day23.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from day23.lib.classes import Maze, Path, Solver, Solver1
from day23.lib.classes import BasePath, Maze, Solver, Solver1
from day23.lib.classes2 import Solver2
from day23.lib.parsers import get_maze

Expand All @@ -17,14 +17,14 @@ def part2(maze: Maze) -> int:


def run_solver(solver: Solver) -> int:
paths: list[Path] = solver.solve()
paths: list[BasePath] = solver.solve()
path_lengths = [len(path) for path in paths]
path_lengths.sort(reverse=True)
return path_lengths[0]


def main() -> None:
maze: Maze = get_maze(INPUT_SMALL)
maze: Maze = get_maze(INPUT)

# print(part1(maze))
print(part2(maze))
Expand Down
13 changes: 9 additions & 4 deletions day23/lib/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ def expand(self) -> list["Position"]:
]


class Path:
class BasePath:
def __len__(self) -> int:
raise NotImplementedError()


class Path(BasePath):
route: list[Position]
nodes: set[Position]

Expand Down Expand Up @@ -119,7 +124,7 @@ def is_oob(self, position: Position) -> bool:


class Solver:
def solve(self) -> list[Path]:
def solve(self) -> list[BasePath]:
return []


Expand All @@ -131,13 +136,13 @@ def __init__(self, maze: Maze, handle_hills: bool = True) -> None:
self.maze = maze
self.handle_hills = handle_hills

def solve(self) -> list[Path]:
def solve(self) -> list[BasePath]:
paths: Queue[Path] = Queue()
first_path = Path()
first_path.add(Position(0, 1))
paths.put(first_path)
# bfs all paths simultaneously
results: list[Path] = []
results: list[BasePath] = []
count = 1
while not paths.empty():
path = paths.get()
Expand Down
102 changes: 89 additions & 13 deletions day23/lib/classes2.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
"""part 2 solution"""
import time
from dataclasses import dataclass, field
from queue import Queue

import colorama

from day23.lib.classes import Maze, Path, Position, Solver
from day23.lib.classes import BasePath, Maze, Path, Position, Solver


# first simplify graph to "nodes", then brute force that.
@dataclass
@dataclass(eq=True)
class Node:
name: int
position: Position
edges: list["Edge"] = field(default_factory=list)
name: int = field(compare=True)
position: Position = field(compare=False)
edges: list["Edge"] = field(default_factory=list, repr=False, compare=False)

def __str__(self) -> str:
return f"{self.name}: ({self.position}) {[str(edge) for edge in self.edges]}"
Expand All @@ -30,6 +30,45 @@ def flip(self) -> "Edge":
def __str__(self) -> str:
return f"{self.node1}->{self.node2}, {len(self.path)}"

def __len__(self) -> int:
return len(self.path)


# Same thing as path but with nodes kappa
class NodePath(BasePath):
path: list[int]
node_ids: set[int]
path_length: int

def __init__(self) -> None:
self.path = []
self.node_ids = set()
self.path_length = 0

def can_add(self, node_id: int) -> bool:
return node_id not in self.node_ids

def copy(self) -> "NodePath":
result = NodePath()
result.path = self.path[:]
result.node_ids = self.node_ids.copy()
result.path_length = self.path_length
return result

def add(self, node_id: int, cost: int = 0) -> None:
self.path.append(node_id)
self.node_ids.add(node_id)
self.path_length += cost

def last(self) -> int:
return self.path[-1]

def __str__(self) -> str:
return f"{self.path_length}, {self.node_ids}"

def __len__(self) -> int:
return self.path_length


class Solver2(Solver):
maze: Maze
Expand Down Expand Up @@ -67,9 +106,7 @@ def get_nodes(self) -> dict[Position, Node]:

nodes.append(Node(name, end))
for node in nodes:
self.maze[node.position] = (
colorama.Back.GREEN + str(node.name) + colorama.Back.BLACK
)
self.maze[node.position] = colorama.Back.GREEN + "X" + colorama.Back.BLACK
return {node.position: node for node in nodes}

def fill_node(self, start_node: Node, nodes: dict[Position, Node]) -> None:
Expand Down Expand Up @@ -123,13 +160,52 @@ def expand_path(self, path: Path) -> list[Path]:

return result

def solve(self) -> list[Path]:
def expand_node_path(
self, node_path: NodePath, nodes: list[Node]
) -> list[NodePath]:
last_node: Node = nodes[node_path.last()]
result = []
for edge in last_node.edges:
target_node_id: int = edge.node2
if node_path.can_add(target_node_id):
to_add = node_path.copy()
to_add.add(target_node_id, len(edge.path))
result.append(to_add)
return result

def build_nodes(self) -> list[Node]:
nodes: dict[Position, Node] = self.get_nodes()
print(self.maze)
for node in nodes.values():
self.fill_node(node, nodes)

for node in nodes.values():
print(node)
return list(nodes.values())

def solve(self) -> list[BasePath]:
nodes: list[Node] = self.build_nodes()
first_path = NodePath()
first_path.add(0)
paths: Queue[NodePath] = Queue()
paths.put(first_path)
print("\n".join(str(node) for node in nodes))
last = time.time()
results: list[BasePath] = []
count = 0
while not paths.empty():
path: NodePath = paths.get()
node_id: int = path.last()
if node_id == nodes[-1].name: # end node
# reached an edge
count += 1
results.append(path)
if count % 10000 == 0:
print(paths.qsize(), path, time.time() - last)
last = time.time()
continue
expansions = self.expand_node_path(path, nodes)
for path in expansions:
paths.put(path)

results.sort(key=lambda x: len(x), reverse=True)

return []
return results

0 comments on commit 4992ffb

Please sign in to comment.