day19 - did solve p1; very, very slowly; doesn't solve p2
This commit is contained in:
parent
25a44b3544
commit
f6f677ae5a
78
day19.py
78
day19.py
@ -11,9 +11,10 @@ class Material(Enum):
|
|||||||
|
|
||||||
|
|
||||||
class Robot:
|
class Robot:
|
||||||
def __init__(self, produces: Material, costs: dict):
|
def __init__(self, produces: Material, costs: dict, min_viable: int = 0):
|
||||||
self.produces = produces
|
self.produces = produces
|
||||||
self.costs = costs
|
self.costs = costs
|
||||||
|
self.min_viable = min_viable
|
||||||
|
|
||||||
|
|
||||||
class Blueprint:
|
class Blueprint:
|
||||||
@ -36,7 +37,7 @@ class Inventory:
|
|||||||
Material.OBSIDIAN: 0,
|
Material.OBSIDIAN: 0,
|
||||||
Material.GEODE: 0,
|
Material.GEODE: 0,
|
||||||
}
|
}
|
||||||
self.build_queue = []
|
self.__build_queue = []
|
||||||
|
|
||||||
def gather(self) -> None:
|
def gather(self) -> None:
|
||||||
for mat, amount in self.robots.items():
|
for mat, amount in self.robots.items():
|
||||||
@ -45,12 +46,12 @@ class Inventory:
|
|||||||
def queue_build_robot(self, robot: Robot) -> None:
|
def queue_build_robot(self, robot: Robot) -> None:
|
||||||
for cost_mat, cost_amount in robot.costs.items():
|
for cost_mat, cost_amount in robot.costs.items():
|
||||||
self.materials[cost_mat] -= cost_amount
|
self.materials[cost_mat] -= cost_amount
|
||||||
self.build_queue.append(robot)
|
self.__build_queue.append(robot)
|
||||||
|
|
||||||
def build_queued_robots(self) -> None:
|
def build_queued_robots(self) -> None:
|
||||||
for robot in self.build_queue:
|
for robot in self.__build_queue:
|
||||||
self.robots[robot.produces] += 1
|
self.robots[robot.produces] += 1
|
||||||
self.build_queue = []
|
self.__build_queue = []
|
||||||
|
|
||||||
def build_robot(self, robot: Robot) -> None:
|
def build_robot(self, robot: Robot) -> None:
|
||||||
self.queue_build_robot(robot)
|
self.queue_build_robot(robot)
|
||||||
@ -63,7 +64,7 @@ class Inventory:
|
|||||||
return new_inv
|
return new_inv
|
||||||
|
|
||||||
|
|
||||||
def pass_minute(bp: Blueprint, inv: Inventory, ignore: list) -> list:
|
def pass_minute(bp: Blueprint, inv: Inventory, ignore: list) -> (Inventory, list):
|
||||||
could_build = []
|
could_build = []
|
||||||
for mat in Material:
|
for mat in Material:
|
||||||
for robot_mat, robot_cost in bp.robots[mat].costs.items():
|
for robot_mat, robot_cost in bp.robots[mat].costs.items():
|
||||||
@ -75,47 +76,44 @@ def pass_minute(bp: Blueprint, inv: Inventory, ignore: list) -> list:
|
|||||||
|
|
||||||
inv.gather()
|
inv.gather()
|
||||||
|
|
||||||
return could_build
|
return inv, could_build
|
||||||
|
|
||||||
|
|
||||||
def get_quality(bp: Blueprint, inv: Inventory, ignore: list, time_left: int = 24, min_geode: int = 0) -> (int, int):
|
def get_quality(bp: Blueprint, inv: Inventory, ignore: list, time_left: int = 24) -> int:
|
||||||
#print("get_quality", time_left, inv.materials, inv.robots)
|
|
||||||
for m in range(time_left):
|
for m in range(time_left):
|
||||||
could_build = pass_minute(bp, inv, ignore)
|
inv, could_build = pass_minute(bp, inv, ignore)
|
||||||
if bp.robots[Material.GEODE] in could_build and time_left - m > min_geode:
|
|
||||||
min_geode = time_left - m
|
|
||||||
print("Can build Geode Robot with", min_geode, "min left.")
|
|
||||||
print(inv.robots, inv.materials)
|
|
||||||
|
|
||||||
if could_build and time_left - m > 1 and (inv.robots[Material.GEODE] > 0 or time_left > min_geode):
|
if could_build and time_left - m > 1:
|
||||||
max_quality = 0
|
max_quality = 0
|
||||||
|
build_a_bot = False
|
||||||
for robot in could_build:
|
for robot in could_build:
|
||||||
|
if robot.min_viable > time_left - m:
|
||||||
|
continue
|
||||||
sub_inv = inv.copy()
|
sub_inv = inv.copy()
|
||||||
sub_inv.build_robot(robot)
|
sub_inv.build_robot(robot)
|
||||||
sub_quality, sub_min_geode = get_quality(bp, sub_inv, [], time_left - m - 1, min_geode)
|
sub_quality = get_quality(bp, sub_inv, [], time_left - m - 1)
|
||||||
if sub_quality > max_quality:
|
if sub_quality > max_quality:
|
||||||
max_quality = sub_quality
|
max_quality = sub_quality
|
||||||
if sub_min_geode > min_geode:
|
build_a_bot = True
|
||||||
min_geode = sub_min_geode
|
|
||||||
|
|
||||||
sub_quality, sub_min_geode = get_quality(bp, inv, could_build, time_left - m - 1, min_geode)
|
if build_a_bot:
|
||||||
if sub_quality > max_quality:
|
sub_quality = get_quality(bp, inv, could_build, time_left - m - 1)
|
||||||
max_quality = sub_quality
|
if sub_quality > max_quality:
|
||||||
if sub_min_geode > min_geode:
|
max_quality = sub_quality
|
||||||
min_geode = sub_min_geode
|
|
||||||
|
|
||||||
return max_quality, min_geode
|
return max_quality
|
||||||
|
|
||||||
return inv.materials[Material.GEODE], min_geode
|
return inv.materials[Material.GEODE]
|
||||||
|
|
||||||
|
|
||||||
class Day(AOCDay):
|
class Day(AOCDay):
|
||||||
inputs = [
|
inputs = [
|
||||||
[
|
[
|
||||||
(33, "input19_test"),
|
(33, "input19_test"),
|
||||||
(None, "input19"),
|
(1616, "input19"),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
(56*62, "input19_test"),
|
||||||
(None, "input19"),
|
(None, "input19"),
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -132,10 +130,10 @@ class Day(AOCDay):
|
|||||||
geode_ore_cost = int(parts[27])
|
geode_ore_cost = int(parts[27])
|
||||||
geode_obsi_cost = int(parts[30])
|
geode_obsi_cost = int(parts[30])
|
||||||
robots = {
|
robots = {
|
||||||
Material.ORE: Robot(Material.ORE, {Material.ORE: ore_ore_cost}),
|
Material.ORE: Robot(Material.ORE, {Material.ORE: ore_ore_cost}, 7),
|
||||||
Material.CLAY: Robot(Material.CLAY, {Material.ORE: clay_ore_cost}),
|
Material.CLAY: Robot(Material.CLAY, {Material.ORE: clay_ore_cost}, 5),
|
||||||
Material.OBSIDIAN: Robot(Material.OBSIDIAN, {Material.ORE: obsi_ore_cost, Material.CLAY: obsi_clay_cost}),
|
Material.OBSIDIAN: Robot(Material.OBSIDIAN, {Material.ORE: obsi_ore_cost, Material.CLAY: obsi_clay_cost}, 3),
|
||||||
Material.GEODE: Robot(Material.GEODE, {Material.ORE: geode_ore_cost, Material.OBSIDIAN: geode_obsi_cost})
|
Material.GEODE: Robot(Material.GEODE, {Material.ORE: geode_ore_cost, Material.OBSIDIAN: geode_obsi_cost}, 1)
|
||||||
}
|
}
|
||||||
bp.append(Blueprint(blueprint_id, robots))
|
bp.append(Blueprint(blueprint_id, robots))
|
||||||
|
|
||||||
@ -143,15 +141,21 @@ class Day(AOCDay):
|
|||||||
|
|
||||||
def part1(self) -> Any:
|
def part1(self) -> Any:
|
||||||
blueprints = self.get_blueprints()
|
blueprints = self.get_blueprints()
|
||||||
#for b in blueprints:
|
score = 0
|
||||||
b = blueprints[0]
|
for b in blueprints:
|
||||||
print("BP", b.bp_id, "Q", get_quality(b, Inventory(), [], 24))
|
quality = get_quality(b, Inventory(), [])
|
||||||
b = blueprints[1]
|
print("BP", b.bp_id, "Q", quality)
|
||||||
print("BP", b.bp_id, "Q", get_quality(b, Inventory(), [], 24))
|
score += quality * b.bp_id
|
||||||
return ""
|
return score
|
||||||
|
|
||||||
def part2(self) -> Any:
|
def part2(self) -> Any:
|
||||||
return ""
|
blueprints = self.get_blueprints()
|
||||||
|
score = 1
|
||||||
|
for b in blueprints[:3]:
|
||||||
|
quality = get_quality(b, Inventory(), [], 32)
|
||||||
|
print("BP", b.bp_id, "Q", quality)
|
||||||
|
score *= quality
|
||||||
|
return score
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user