Blake Rayvid - https://github.com/brayvid
Make the most of the ingredients you have. Maximize total magnitude (essentially in-game value) with integer linear programming in scipy.
import numpy as np
import pandas as pd
from scipy.optimize import milp, Bounds, LinearConstraint
Uses local files "ingredients_have.csv" and "recipes_can_make.csv"
I made my CSVs using this helpful spreadsheet: https://docs.google.com/spreadsheets/d/1010C6ltqv7apuBoNYuFIFSBZER4YI03Y54kIsoKs5RI/edit?usp=sharing
# Ingredients we have with quantity on hand
ingredients = pd.read_csv('ingredients_have.csv');ingredients
Ingredient | Quantity | |
---|---|---|
0 | Blisterwort | 4 |
1 | Blue Butterfly Wing | 4 |
2 | Blue Dartwing | 1 |
3 | Blue Mountain Flower | 24 |
4 | Bone Meal | 5 |
5 | Butterfly Wing | 6 |
6 | Canis Root | 2 |
7 | Creep Cluster | 1 |
8 | Deathbell | 6 |
9 | Dragons Tongue | 5 |
10 | Ectoplasm | 5 |
11 | Elves Ear | 10 |
12 | Fire Salts | 1 |
13 | Fly Amanita | 1 |
14 | Frost Mirriam | 3 |
15 | Garlic | 7 |
16 | Giant Lichen | 2 |
17 | Glow Dust | 2 |
18 | Hagraven Feathers | 2 |
19 | Histcarp | 2 |
20 | Honeycomb | 4 |
21 | Ice Wraith Teeth | 2 |
22 | Imp Stool | 2 |
23 | Lavender | 17 |
24 | Luna Moth Wing | 4 |
25 | Mora Tapinella | 2 |
26 | Mudcrab Chitin | 2 |
27 | Nightshade | 7 |
28 | Nirnroot | 3 |
29 | Nordic Barnacle | 2 |
30 | Orange Dartwing | 2 |
31 | Purple Mountain Flower | 15 |
32 | Red Mountain Flower | 1 |
33 | River Betty | 2 |
34 | Rock Warbler Egg | 3 |
35 | Salt Pile | 14 |
36 | Scaly Pholiota | 1 |
37 | Skeever Tail | 2 |
38 | Slaughterfish Scales | 3 |
39 | Snowberries | 6 |
40 | Spider Egg | 8 |
41 | Spriggan Sap | 3 |
42 | Swamp Fungal Pod | 2 |
43 | Taproot | 2 |
44 | Thistle Branch | 2 |
45 | Torchbug Thorax | 3 |
46 | Troll Fat | 3 |
47 | Tundra Cotton | 7 |
48 | Vampire Dust | 1 |
49 | Void Salts | 1 |
50 | White Cap | 6 |
# Potions list with magnitude and ingredient names (1,2 + optional 3rd)
recipes = pd.read_csv('recipes_can_make.csv')
recipes = recipes[recipes['Magnitude'] > 0]
recipes[['Magnitude','Ingredient 1','Ingredient 2','Ingredient 3','MyPotionID']].head(50)
Magnitude | Ingredient 1 | Ingredient 2 | Ingredient 3 | MyPotionID | |
---|---|---|---|---|---|
0 | 159 | Blue Dartwing | Blue Mountain Flower | Glow Dust | 3028 |
1 | 156 | Blue Dartwing | Blue Mountain Flower | Nightshade | 3037 |
2 | 156 | Blue Dartwing | Blue Mountain Flower | Spider Egg | 3045 |
3 | 156 | Blue Dartwing | Blue Mountain Flower | Spriggan Sap | 3046 |
4 | 113 | Blisterwort | Blue Butterfly Wing | Blue Mountain Flower | 2130 |
5 | 113 | Blue Butterfly Wing | Blue Mountain Flower | Rock Warbler Egg | 2680 |
6 | 112 | Frost Mirriam | Histcarp | Purple Mountain Flower | 10371 |
7 | 110 | Blue Butterfly Wing | Blue Mountain Flower | Butterfly Wing | 2666 |
8 | 110 | Blue Butterfly Wing | Blue Mountain Flower | Imp Stool | 2677 |
9 | 110 | Blue Butterfly Wing | Blue Mountain Flower | Swamp Fungal Pod | 2684 |
10 | 110 | Glow Dust | Nightshade | River Betty | 11628 |
11 | 109 | Blisterwort | Blue Mountain Flower | Spriggan Sap | 2210 |
12 | 109 | Blue Butterfly Wing | Bone Meal | Spriggan Sap | 2703 |
13 | 109 | Butterfly Wing | Glow Dust | Nightshade | 4738 |
14 | 109 | Creep Cluster | Ectoplasm | Histcarp | 6302 |
15 | 109 | Creep Cluster | Histcarp | Red Mountain Flower | 6550 |
16 | 109 | Creep Cluster | River Betty | Skeever Tail | 6725 |
17 | 109 | Nightshade | River Betty | Spriggan Sap | 14461 |
18 | 108 | Blisterwort | Blue Butterfly Wing | Spriggan Sap | 2154 |
19 | 108 | Blisterwort | Blue Mountain Flower | Spider Egg | 2209 |
20 | 108 | Blue Butterfly Wing | Blue Mountain Flower | Bone Meal | 2665 |
21 | 108 | Blue Butterfly Wing | Blue Mountain Flower | Canis Root | 2667 |
22 | 108 | Blue Butterfly Wing | Blue Mountain Flower | Nirnroot | 2679 |
23 | 108 | Blue Butterfly Wing | Blue Mountain Flower | Spider Egg | 2682 |
24 | 108 | Blue Butterfly Wing | Bone Meal | Glow Dust | 2693 |
25 | 108 | Blue Butterfly Wing | Bone Meal | Nightshade | 2700 |
26 | 108 | Blue Butterfly Wing | Bone Meal | Spider Egg | 2702 |
27 | 108 | Blue Butterfly Wing | Glow Dust | Hagraven Feathers | 2860 |
28 | 108 | Blue Butterfly Wing | Hagraven Feathers | Spider Egg | 2908 |
29 | 108 | Blue Butterfly Wing | Lavender | Spider Egg | 2969 |
30 | 108 | Blue Dartwing | Glow Dust | Nightshade | 3203 |
31 | 108 | Blue Mountain Flower | Bone Meal | Spider Egg | 3416 |
32 | 108 | Blue Mountain Flower | Butterfly Wing | Glow Dust | 3429 |
33 | 108 | Blue Mountain Flower | Glow Dust | Hagraven Feathers | 3628 |
34 | 108 | Blue Mountain Flower | Glow Dust | Swamp Fungal Pod | 3643 |
35 | 108 | Blue Mountain Flower | Rock Warbler Egg | Spider Egg | 3780 |
36 | 108 | Glow Dust | Hagraven Feathers | Nightshade | 11513 |
37 | 108 | Glow Dust | Luna Moth Wing | Nightshade | 11598 |
38 | 108 | Glow Dust | Nightshade | Nordic Barnacle | 11624 |
39 | 108 | Glow Dust | Nightshade | Snowberries | 11631 |
40 | 108 | Glow Dust | Nightshade | Swamp Fungal Pod | 11632 |
41 | 107 | Blisterwort | Spider Egg | Spriggan Sap | 2648 |
42 | 107 | Blue Butterfly Wing | Canis Root | Spider Egg | 2724 |
43 | 107 | Blue Mountain Flower | Imp Stool | Nightshade | 3716 |
44 | 107 | Canis Root | Spider Egg | Spriggan Sap | 5163 |
45 | 107 | Creep Cluster | Ectoplasm | Skeever Tail | 6318 |
46 | 107 | Creep Cluster | Frost Mirriam | Purple Mountain Flower | 6392 |
47 | 107 | Creep Cluster | Frost Mirriam | Red Mountain Flower | 6393 |
48 | 107 | Creep Cluster | Frost Mirriam | Taproot | 6402 |
49 | 107 | Creep Cluster | Frost Mirriam | White Cap | 6406 |
One row for each ingredient, one column for each potion. "1" indicates the ingredient is used in the potion.
# Boolean matrix A says what ingredients are in what recipes
A = pd.DataFrame(0, index=range(len(ingredients)),columns=range(len(recipes)))
for i in range(len(recipes)):
if ingredients.iloc[ingredients["Ingredient"].str.find(recipes.loc[i, "Ingredient 1"]).idxmax()]["Quantity"] > 0:
A.iloc[ingredients["Ingredient"].str.find(recipes.loc[i, "Ingredient 1"]).idxmax(), i] = 1
if ingredients.iloc[ingredients["Ingredient"].str.find(recipes.loc[i, "Ingredient 2"]).idxmax()]["Quantity"] > 0:
A.iloc[ingredients["Ingredient"].str.find(recipes.loc[i, "Ingredient 2"]).idxmax(), i] = 1
if not pd.isnull(recipes.loc[i, "Ingredient 3"]):
if ingredients.iloc[ingredients["Ingredient"].str.find(recipes.loc[i, "Ingredient 3"]).idxmax()]["Quantity"] > 0:
A.iloc[ingredients["Ingredient"].str.find(recipes.loc[i, "Ingredient 3"]).idxmax(), i] = 1
A
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ... | 2375 | 2376 | 2377 | 2378 | 2379 | 2380 | 2381 | 2382 | 2383 | 2384 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
3 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
10 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
12 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
13 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
14 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
16 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
17 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
18 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
19 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
20 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
22 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
23 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 |
24 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
25 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
26 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
27 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
28 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
29 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
30 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
31 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
32 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
33 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
34 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
35 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
36 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
37 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
38 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
39 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
40 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
41 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
42 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
43 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
44 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
45 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
46 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
47 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 1 |
48 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
49 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
50 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
51 rows × 2385 columns
find x to minimize f.x with Ax <= b, x >= lb
f = -1 * magnitude, b = qty of each ingredient on hand
# Objective function f.x to minimize
f = np.array(-1 * recipes['Magnitude'],dtype=int); # f = -1*value so that minimizing f.x maximizes total value
# Bounds
b_max = np.array(ingredients['Quantity'],dtype=int) # Cannot use more than we have on hand
x_lb = np.zeros(shape=len(recipes)) # Cannot use less than 0
# milp parameters
bounds = Bounds(lb=x_lb)
constraint = LinearConstraint(A, ub=b_max)
integrality = np.ones(shape=len(recipes),dtype=int) # All x should be integers
# Perform optimization
res = milp(c=f, integrality=integrality, bounds=bounds, constraints=constraint)
# Display the potions we should make to maximize magnitude where the last column is quantity to make
total_magnitude = int(-res.fun)
num_potions = int(sum(res.x))
indices_to_make = np.nonzero(res.x > 0)
to_make_df = recipes.iloc[indices_to_make].copy()
to_make_df.loc[:,'QtyToMake'] = res.x[indices_to_make].astype(int)
to_make_df[['Magnitude','Type','Ingredient 1','Ingredient 2','Ingredient 3','MyPotionID','QtyToMake']].head(50)
Magnitude | Type | Ingredient 1 | Ingredient 2 | Ingredient 3 | MyPotionID | QtyToMake | |
---|---|---|---|---|---|---|---|
6 | 112 | Mixed | Frost Mirriam | Histcarp | Purple Mountain Flower | 10371 | 2 |
7 | 110 | Mixed | Blue Butterfly Wing | Blue Mountain Flower | Butterfly Wing | 2666 | 4 |
11 | 109 | Mixed | Blisterwort | Blue Mountain Flower | Spriggan Sap | 2210 | 3 |
19 | 108 | Mixed | Blisterwort | Blue Mountain Flower | Spider Egg | 2209 | 1 |
31 | 108 | Mixed | Blue Mountain Flower | Bone Meal | Spider Egg | 3416 | 4 |
33 | 108 | Mixed | Blue Mountain Flower | Glow Dust | Hagraven Feathers | 3628 | 1 |
34 | 108 | Mixed | Blue Mountain Flower | Glow Dust | Swamp Fungal Pod | 3643 | 1 |
35 | 108 | Mixed | Blue Mountain Flower | Rock Warbler Egg | Spider Egg | 3780 | 1 |
45 | 107 | Mixed | Creep Cluster | Ectoplasm | Skeever Tail | 6318 | 1 |
57 | 107 | Mixed | Frost Mirriam | Purple Mountain Flower | Skeever Tail | 10519 | 1 |
103 | 105 | Mixed | Blue Mountain Flower | Lavender | Nightshade | 3749 | 7 |
104 | 105 | Mixed | Blue Mountain Flower | Lavender | Spider Egg | 3755 | 2 |
303 | 59 | Potion | Blue Dartwing | Swamp Fungal Pod | NaN | 3388 | 1 |
334 | 57 | Mixed | Deathbell | Salt Pile | Taproot | 8001 | 1 |
361 | 55 | Poison | River Betty | Salt Pile | Troll Fat | 15006 | 2 |
367 | 53 | Poison | Deathbell | Nirnroot | Salt Pile | 7937 | 2 |
370 | 53 | Poison | Deathbell | Salt Pile | Troll Fat | 8004 | 1 |
379 | 50 | Poison | Deathbell | Salt Pile | NaN | 8006 | 2 |
384 | 17 | Mixed | Elves Ear | Fire Salts | Salt Pile | 8930 | 1 |
391 | 16 | Potion | Dragons Tongue | Fly Amanita | Scaly Pholiota | 8094 | 1 |
397 | 15 | Potion | Garlic | Taproot | Vampire Dust | 11060 | 1 |
400 | 14 | Mixed | Ectoplasm | Giant Lichen | Void Salts | 8576 | 1 |
443 | 12 | Mixed | Canis Root | Imp Stool | Rock Warbler Egg | 5088 | 2 |
461 | 12 | Mixed | Luna Moth Wing | Nordic Barnacle | Orange Dartwing | 14094 | 1 |
465 | 12 | Potion | Dragons Tongue | Elves Ear | Mora Tapinella | 8058 | 2 |
468 | 12 | Potion | Honeycomb | Purple Mountain Flower | Slaughterfish Scales | 12905 | 1 |
469 | 12 | Potion | Mudcrab Chitin | Purple Mountain Flower | Thistle Branch | 14343 | 2 |
470 | 11 | Mixed | Ectoplasm | Red Mountain Flower | NaN | 8873 | 1 |
493 | 11 | Mixed | Dragons Tongue | Elves Ear | White Cap | 8067 | 2 |
516 | 11 | Mixed | Elves Ear | Snowberries | White Cap | 9130 | 2 |
582 | 10 | Mixed | Elves Ear | Ice Wraith Teeth | White Cap | 9037 | 2 |
658 | 9 | Mixed | Bone Meal | Lavender | Nirnroot | 4095 | 1 |
704 | 9 | Mixed | Purple Mountain Flower | Snowberries | Torchbug Thorax | 14933 | 3 |
760 | 9 | Potion | Ectoplasm | Elves Ear | Tundra Cotton | 8459 | 1 |
765 | 9 | Potion | Ectoplasm | Giant Lichen | Tundra Cotton | 8575 | 1 |
804 | 9 | Potion | Garlic | Lavender | Luna Moth Wing | 10953 | 1 |
806 | 9 | Potion | Garlic | Lavender | Salt Pile | 10961 | 5 |
855 | 9 | Potion | Honeycomb | Purple Mountain Flower | Tundra Cotton | 12911 | 3 |
879 | 8 | Mixed | Luna Moth Wing | Nordic Barnacle | NaN | 14098 | 1 |
1017 | 8 | Mixed | Hagraven Feathers | Lavender | Luna Moth Wing | 12101 | 1 |
1144 | 8 | Potion | Orange Dartwing | Purple Mountain Flower | Snowberries | 14612 | 1 |
1443 | 7 | Potion | Purple Mountain Flower | Slaughterfish Scales | Tundra Cotton | 14922 | 2 |
print(f"To maximize magnitude and therefore value, create {num_potions} potions of the {len(to_make_df)} unique types listed above for a total magnitude of {total_magnitude}.")
To maximize magnitude and therefore value, create 76 potions of the 42 unique types listed above for a total magnitude of 3905.