day23; having to work really doesn't help solving puzzles
This commit is contained in:
parent
8b4e3b9951
commit
c15534c0aa
52
day23.py
52
day23.py
@ -1,10 +1,12 @@
|
|||||||
from tools.aoc import AOCDay
|
from tools.aoc import AOCDay
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
import sys
|
||||||
|
sys.setrecursionlimit(2000)
|
||||||
|
|
||||||
|
|
||||||
def getLegalMoves(positions):
|
def getLegalMoves(positions):
|
||||||
#print(positions)
|
|
||||||
movers = [c for c in positions if positions[c]]
|
movers = [c for c in positions if positions[c]]
|
||||||
|
moves = []
|
||||||
|
|
||||||
for start in movers:
|
for start in movers:
|
||||||
finalPosition = True
|
finalPosition = True
|
||||||
@ -14,7 +16,6 @@ def getLegalMoves(positions):
|
|||||||
if start[1] > 0 and start[0] == positions[start] * 2:
|
if start[1] > 0 and start[0] == positions[start] * 2:
|
||||||
for y in range(start[1] + 1, 5):
|
for y in range(start[1] + 1, 5):
|
||||||
if (start[0], y) in positions and positions[(start[0], y)] != positions[start]:
|
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
|
finalPosition = False
|
||||||
|
|
||||||
if finalPosition:
|
if finalPosition:
|
||||||
@ -38,15 +39,14 @@ def getLegalMoves(positions):
|
|||||||
|
|
||||||
possible_targets.append(target)
|
possible_targets.append(target)
|
||||||
break
|
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:
|
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:
|
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
|
continue
|
||||||
|
|
||||||
wayClear = True
|
wayClear = True
|
||||||
@ -57,18 +57,21 @@ def getLegalMoves(positions):
|
|||||||
if not wayClear:
|
if not wayClear:
|
||||||
continue
|
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 = {}
|
DP = {}
|
||||||
|
|
||||||
|
|
||||||
def isFinalPosition(position, cost):
|
def isFinalPosition(position, cost):
|
||||||
global gMinCost, DP
|
global gMinCost
|
||||||
for x in 2, 4, 6, 8:
|
for x in 2, 4, 6, 8:
|
||||||
for y in 1, 2:
|
for y in 1, 2, 3, 4:
|
||||||
if position[(x, y)] != x // 2:
|
if (x, y) in position and position[(x, y)] != x // 2:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if gMinCost > cost:
|
if gMinCost > cost:
|
||||||
@ -78,26 +81,25 @@ def isFinalPosition(position, cost):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def play(position, cost, currentMinCost):
|
def play(position, cost):
|
||||||
if cost > gMinCost:
|
|
||||||
return 1e9
|
|
||||||
if (str(position), cost) in DP:
|
if (str(position), cost) in DP:
|
||||||
return DP[str(position), cost]
|
return DP[str(position), cost]
|
||||||
|
|
||||||
minCost = currentMinCost
|
minCost = 5e4
|
||||||
for move in getLegalMoves(position):
|
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 = position.copy()
|
||||||
new_pos[move[1]] = new_pos[move[0]]
|
new_pos[move[1]] = new_pos[move[0]]
|
||||||
new_pos[move[0]] = 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):
|
if not isFinalPosition(new_pos, this_cost):
|
||||||
this_cost += play(new_pos, this_cost, minCost)
|
this_cost += play(new_pos, this_cost)
|
||||||
DP[str(new_pos), cost + 10 ** (new_pos[move[1]] - 1) * move[2]] = this_cost
|
|
||||||
if this_cost < minCost:
|
if this_cost < minCost:
|
||||||
minCost = this_cost
|
minCost = this_cost
|
||||||
|
|
||||||
|
DP[str(position), cost] = minCost
|
||||||
return minCost
|
return minCost
|
||||||
|
|
||||||
|
|
||||||
@ -142,16 +144,16 @@ class Day(AOCDay):
|
|||||||
|
|
||||||
def part1(self) -> Any:
|
def part1(self) -> Any:
|
||||||
global gMinCost
|
global gMinCost
|
||||||
gMinCost = 1e9
|
gMinCost = 5e4
|
||||||
initPos = self.getStartingPosition()
|
initPos = self.getStartingPosition()
|
||||||
play(initPos, 0, 1e9)
|
print(play(initPos, 0))
|
||||||
return gMinCost
|
return gMinCost
|
||||||
|
|
||||||
def part2(self) -> Any:
|
def part2(self) -> Any:
|
||||||
global gMinCost
|
global gMinCost
|
||||||
gMinCost = 1e9
|
gMinCost = 5e4
|
||||||
initPos = self.getStartingPosition(part2=True)
|
initPos = self.getStartingPosition(part2=True)
|
||||||
print(initPos)
|
print(initPos)
|
||||||
print(len(list(getLegalMoves(initPos))), list(getLegalMoves(initPos)))
|
print(len(list(getLegalMoves(initPos))), list(getLegalMoves(initPos)))
|
||||||
play(initPos, 0, 1e9)
|
play(initPos, 0)
|
||||||
return gMinCost
|
return gMinCost
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user