109 lines
4.1 KiB
Python
109 lines
4.1 KiB
Python
import numpy as np
|
|
|
|
|
|
class Ingredient:
|
|
def __init__(self, name: str, capacity: int, durability: int, flavour: int, texture: int, calories: int):
|
|
self.name = name
|
|
self.capacity = capacity
|
|
self.durability = durability
|
|
self.flavour = flavour
|
|
self.texture = texture
|
|
self.calories = calories
|
|
|
|
def get_all(self) -> list[int]:
|
|
return [self.capacity, self.durability, self.flavour, self.texture, self.calories]
|
|
|
|
|
|
class Recipe:
|
|
def __init__(self):
|
|
self.ingredients = []
|
|
self.best_mix = list
|
|
self.best_score = int
|
|
self.healthy_mix = list
|
|
self.healthy_score = int
|
|
|
|
def load_ingredient(self, ingredients: list[str]) -> None:
|
|
for ingredient in ingredients:
|
|
name, rest = ingredient.split(':')
|
|
capacity, durability, flavour, texture, calories = rest.split(',')
|
|
capacity = int(capacity.strip().split(' ')[1])
|
|
durability = int(durability.strip().split(' ')[1])
|
|
flavour = int(flavour.strip().split(' ')[1])
|
|
texture = int(texture.strip().split(' ')[1])
|
|
calories = int(calories.strip().split(' ')[1])
|
|
self.ingredients.append(Ingredient(name, capacity, durability, flavour, texture, calories))
|
|
|
|
def calculate_best_mix(self) -> None:
|
|
# example data: [(14, Ingredient1), (86, Ingredient2)]
|
|
def calculate_score(ratio_and_ingredients: list[tuple[int, Ingredient]]) -> tuple[int, int]:
|
|
scores = []
|
|
for i in ratio_and_ingredients:
|
|
ratio, ingredient = i[0], i[1]
|
|
total_score = [ratio * j for j in ingredient.get_all()]
|
|
scores.append(total_score)
|
|
|
|
total_score = scores.pop(0)
|
|
for score in scores:
|
|
total_score = np.add(score, total_score)
|
|
for i, score in enumerate(total_score):
|
|
if score < 0:
|
|
total_score[i] = 0
|
|
|
|
return total_score[0] * total_score[1] * total_score[2] * total_score[3], total_score[4]
|
|
|
|
def recursive_rest(iteration: int, rest: int) -> list[list[int]]:
|
|
if iteration == len(self.ingredients):
|
|
return [[rest]]
|
|
combinations = []
|
|
for i in np.arange(rest + 1):
|
|
for j in recursive_rest(iteration + 1, rest - int(i)):
|
|
new_combination = j
|
|
new_combination.insert(0, int(i))
|
|
combinations.append(new_combination)
|
|
return combinations
|
|
|
|
all_combinations = recursive_rest(1, 100)
|
|
best_mix = []
|
|
best_score = 0
|
|
|
|
healthy_mix = []
|
|
healthy_score = 0
|
|
for combination in all_combinations:
|
|
final_combination = []
|
|
for index, value in enumerate(combination):
|
|
final_combination.append((value, self.ingredients[index]))
|
|
score, calories = calculate_score(final_combination)
|
|
if score > best_score:
|
|
best_mix = final_combination
|
|
best_score = score
|
|
if calories == 500:
|
|
if score > healthy_score:
|
|
healthy_mix = final_combination
|
|
healthy_score = score
|
|
|
|
self.best_mix = best_mix
|
|
self.best_score = best_score
|
|
|
|
self.healthy_mix = healthy_mix
|
|
self.healthy_score = healthy_score
|
|
|
|
|
|
if __name__ == '__main__':
|
|
test_recipe = Recipe()
|
|
test_recipe.load_ingredient(["Butterscotch: capacity -1, durability -2, flavor 6, texture 3, calories 8",
|
|
"Cinnamon: capacity 2, durability 3, flavor -2, texture -1, calories 3"])
|
|
test_recipe.calculate_best_mix()
|
|
assert test_recipe.best_score == 62842880, "Error: Example couldn't be calculated."
|
|
assert test_recipe.healthy_score == 57600000, "Error: Example 2 couldn't be calculated."
|
|
print("All test passed")
|
|
|
|
puzzle_input = open("input.txt", "r").read().splitlines()
|
|
recipe = Recipe()
|
|
recipe.load_ingredient(puzzle_input)
|
|
recipe.calculate_best_mix()
|
|
|
|
print("solution: ", recipe.best_score)
|
|
|
|
print("Part2: ")
|
|
print("solution: ", recipe.healthy_score)
|