diff --git a/day23.py b/day23.py index d73c1f4..7998ec4 100644 --- a/day23.py +++ b/day23.py @@ -1,10 +1,12 @@ from tools.aoc import AOCDay from typing import Any +import sys +sys.setrecursionlimit(2000) def getLegalMoves(positions): - #print(positions) movers = [c for c in positions if positions[c]] + moves = [] for start in movers: finalPosition = True @@ -14,7 +16,6 @@ def getLegalMoves(positions): if start[1] > 0 and start[0] == positions[start] * 2: for y in range(start[1] + 1, 5): if (start[0], y) in positions and positions[(start[0], y)] != positions[start]: - #print("I'm in the right pot, but wrong position:", positions[start], start, positions[(start[0], y)], (start[0], y)) finalPosition = False if finalPosition: @@ -38,15 +39,14 @@ def getLegalMoves(positions): possible_targets.append(target) break - #possible_targets = [(positions[start] * 2, 2)] - #if positions[(positions[start] * 2, 2)] == positions[start]: - # possible_targets.extend([(positions[start] * 2, 1)]) if start[1] != 0: - possible_targets.extend([(0, 0), (1, 0), (3, 0), (5, 0), (7, 0), (9, 0), (10, 0)]) + for x in 0, 1, 3, 5, 7, 9, 10: + if not positions[(x, 0)]: + possible_targets.append((x, 0)) for dest in possible_targets: - if start == dest or positions[dest] or start[1] == 2 and positions[(start[0], 1)]: + if start == dest or positions[dest]: continue wayClear = True @@ -57,18 +57,21 @@ def getLegalMoves(positions): if not wayClear: continue - yield start, dest, start[1] + abs(dest[0] - start[0]) + dest[1] + #yield start, dest, start[1] + abs(dest[0] - start[0]) + dest[1] + moves.append((start, dest, start[1] + abs(dest[0] - start[0]) + dest[1])) + + return moves -gMinCost = 1e9 +gMinCost = 1e5 DP = {} def isFinalPosition(position, cost): - global gMinCost, DP + global gMinCost for x in 2, 4, 6, 8: - for y in 1, 2: - if position[(x, y)] != x // 2: + for y in 1, 2, 3, 4: + if (x, y) in position and position[(x, y)] != x // 2: return False if gMinCost > cost: @@ -78,26 +81,25 @@ def isFinalPosition(position, cost): return True -def play(position, cost, currentMinCost): - if cost > gMinCost: - return 1e9 +def play(position, cost): if (str(position), cost) in DP: return DP[str(position), cost] - minCost = currentMinCost + minCost = 5e4 for move in getLegalMoves(position): + move_cost = cost + 10 ** (position[move[0]] - 1) * move[2] + this_cost = move_cost + if this_cost > gMinCost: + continue new_pos = position.copy() new_pos[move[1]] = new_pos[move[0]] new_pos[move[0]] = 0 - this_cost = cost + 10 ** (new_pos[move[1]] - 1) * move[2] - if this_cost > gMinCost: - continue if not isFinalPosition(new_pos, this_cost): - this_cost += play(new_pos, this_cost, minCost) - DP[str(new_pos), cost + 10 ** (new_pos[move[1]] - 1) * move[2]] = this_cost + this_cost += play(new_pos, this_cost) if this_cost < minCost: minCost = this_cost + DP[str(position), cost] = minCost return minCost @@ -142,16 +144,16 @@ class Day(AOCDay): def part1(self) -> Any: global gMinCost - gMinCost = 1e9 + gMinCost = 5e4 initPos = self.getStartingPosition() - play(initPos, 0, 1e9) + print(play(initPos, 0)) return gMinCost def part2(self) -> Any: global gMinCost - gMinCost = 1e9 + gMinCost = 5e4 initPos = self.getStartingPosition(part2=True) print(initPos) print(len(list(getLegalMoves(initPos))), list(getLegalMoves(initPos))) - play(initPos, 0, 1e9) + play(initPos, 0) return gMinCost