day19 - p2 in sub 3min; still to be improved
This commit is contained in:
parent
265f481472
commit
6fdf2d55ff
32
day19.py
32
day19.py
@ -1,10 +1,9 @@
|
|||||||
|
from collections import defaultdict
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from heapq import heappush, heappop
|
from heapq import heappush, heappop
|
||||||
from tools.aoc import AOCDay
|
from tools.aoc import AOCDay
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from tools.int_seq import triangular
|
|
||||||
|
|
||||||
|
|
||||||
class Material(Enum):
|
class Material(Enum):
|
||||||
ORE = 1
|
ORE = 1
|
||||||
@ -51,6 +50,12 @@ class Inventory:
|
|||||||
new_inv.materials = self.materials.copy()
|
new_inv.materials = self.materials.copy()
|
||||||
return new_inv
|
return new_inv
|
||||||
|
|
||||||
|
def value(self) -> int:
|
||||||
|
return self.robots[Material.ORE] \
|
||||||
|
+ 2 * self.robots[Material.CLAY] \
|
||||||
|
+ 4 * self.robots[Material.OBSIDIAN] \
|
||||||
|
+ 8 * self.robots[Material.GEODE]
|
||||||
|
|
||||||
def __lt__(self, other: 'Inventory') -> bool:
|
def __lt__(self, other: 'Inventory') -> bool:
|
||||||
return self.materials[Material.GEODE] < other.materials[Material.GEODE]
|
return self.materials[Material.GEODE] < other.materials[Material.GEODE]
|
||||||
|
|
||||||
@ -84,21 +89,33 @@ def pass_minute(bp: Blueprint, inv: Inventory, ignore: list) -> (Inventory, list
|
|||||||
return inv, could_build
|
return inv, could_build
|
||||||
|
|
||||||
|
|
||||||
def get_bfs_quality(bp: Blueprint, max_time: int = 24) -> int:
|
def get_dfs_quality(bp: Blueprint, max_time: int = 24) -> int:
|
||||||
q = []
|
q = []
|
||||||
max_geode = 0
|
max_geode = 0
|
||||||
|
max_value = defaultdict(int)
|
||||||
heappush(q, (max_time, Inventory(), [], 0))
|
heappush(q, (max_time, Inventory(), [], 0))
|
||||||
|
q_count = 0
|
||||||
while q:
|
while q:
|
||||||
|
q_count += 1
|
||||||
time_left, inv, ignore, no_build = heappop(q)
|
time_left, inv, ignore, no_build = heappop(q)
|
||||||
|
|
||||||
inv, could_build = pass_minute(bp, inv, ignore)
|
inv, could_build = pass_minute(bp, inv, ignore)
|
||||||
time_left -= 1
|
time_left -= 1
|
||||||
|
inv_value = inv.value()
|
||||||
|
if inv_value < max_value[time_left] // 2.1:
|
||||||
|
continue
|
||||||
|
elif inv_value > max_value[time_left]:
|
||||||
|
max_value[time_left] = inv_value
|
||||||
|
|
||||||
if time_left == 0:
|
if time_left == 0:
|
||||||
if inv.materials[Material.GEODE] > max_geode:
|
if inv.materials[Material.GEODE] > max_geode:
|
||||||
max_geode = inv.materials[Material.GEODE]
|
max_geode = inv.materials[Material.GEODE]
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if bp.robots[Material.GEODE] in could_build:
|
||||||
|
inv.build_robot(bp.robots[Material.GEODE])
|
||||||
|
heappush(q, (time_left, inv, [], 0))
|
||||||
|
continue
|
||||||
|
|
||||||
for robot in could_build:
|
for robot in could_build:
|
||||||
if robot.min_viable > time_left:
|
if robot.min_viable > time_left:
|
||||||
continue
|
continue
|
||||||
@ -109,6 +126,7 @@ def get_bfs_quality(bp: Blueprint, max_time: int = 24) -> int:
|
|||||||
if no_build < bp.max_cost[Material.ORE]:
|
if no_build < bp.max_cost[Material.ORE]:
|
||||||
heappush(q, (time_left, inv, could_build, no_build + 1))
|
heappush(q, (time_left, inv, could_build, no_build + 1))
|
||||||
|
|
||||||
|
print(q_count)
|
||||||
return max_geode
|
return max_geode
|
||||||
|
|
||||||
|
|
||||||
@ -119,7 +137,7 @@ class Day(AOCDay):
|
|||||||
(1616, "input19"),
|
(1616, "input19"),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
#(56*62, "input19_test"),
|
(3472, "input19_test"),
|
||||||
(8990, "input19"),
|
(8990, "input19"),
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -149,7 +167,7 @@ class Day(AOCDay):
|
|||||||
blueprints = self.get_blueprints()
|
blueprints = self.get_blueprints()
|
||||||
score = 0
|
score = 0
|
||||||
for b in blueprints:
|
for b in blueprints:
|
||||||
quality = get_bfs_quality(b)
|
quality = get_dfs_quality(b)
|
||||||
score += quality * b.bp_id
|
score += quality * b.bp_id
|
||||||
print("BP", b.bp_id, "Q", quality, "S", score)
|
print("BP", b.bp_id, "Q", quality, "S", score)
|
||||||
return score
|
return score
|
||||||
@ -158,7 +176,7 @@ class Day(AOCDay):
|
|||||||
blueprints = self.get_blueprints()
|
blueprints = self.get_blueprints()
|
||||||
score = 1
|
score = 1
|
||||||
for b in blueprints[:3]:
|
for b in blueprints[:3]:
|
||||||
quality = get_bfs_quality(b, 32)
|
quality = get_dfs_quality(b, 32)
|
||||||
score *= quality
|
score *= quality
|
||||||
print("BP", b.bp_id, "Q", quality, "S", score)
|
print("BP", b.bp_id, "Q", quality, "S", score)
|
||||||
return score
|
return score
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user