Optimising a list searching algorithmSearching a list of pairs of numbersOptimising Funny MarblesList comparison algorithmSearching Combobox drop-down listPerformance of the String searching algorithmOptimising an iterative function over long stringsLet's speed that file sentence searching programKMP algorithm searching from the rightSearching online English dictionariesOptimising fingerprint scan compare process

Constant Current LED Circuit

What if (if any) the reason to buy in small local stores?

What is the significance behind "40 days" that often appears in the Bible?

PTIJ What is the inyan of the Konami code in Uncle Moishy's song?

Print a physical multiplication table

Asserting that Atheism and Theism are both faith based positions

Do US professors/group leaders only get a salary, but no group budget?

What does "^L" mean in C?

Does .bashrc contain syntax errors?

Matrix using tikz package

What exactly term 'companion plants' means?

Is it true that good novels will automatically sell themselves on Amazon (and so on) and there is no need for one to waste time promoting?

Deletion of copy-ctor & copy-assignment - public, private or protected?

Fewest number of steps to reach 200 using special calculator

Is there a hypothetical scenario that would make Earth uninhabitable for humans, but not for (the majority of) other animals?

Is honey really a supersaturated solution? Does heating to un-crystalize redissolve it or melt it?

Do native speakers use "ultima" and "proxima" frequently in spoken English?

How difficult is it to simply disable/disengage the MCAS on Boeing 737 Max 8 & 9 Aircraft?

Fragmentation Level for Heaps

What does "Four-F." mean?

Am I eligible for the Eurail Youth pass? I am 27.5 years old

Suggestions on how to spend Shaabath (constructively) alone

Print last inputted byte

Describing a chess game in a novel



Optimising a list searching algorithm


Searching a list of pairs of numbersOptimising Funny MarblesList comparison algorithmSearching Combobox drop-down listPerformance of the String searching algorithmOptimising an iterative function over long stringsLet's speed that file sentence searching programKMP algorithm searching from the rightSearching online English dictionariesOptimising fingerprint scan compare process













2












$begingroup$


I've created the following code to try and find the optimum "diet" from a game called Eco. The maximum amount of calories you can have is 3000, as shown with MAXCALORIES.



Is there any way to make this code faster, since the time predicted for this code to compute 3000 calories is well over a few hundred years.



Note: I am trying to find the highest SP (skill points) you get from a diet, the optimum diet. To find this, I must go through every combination of diets and check how many skill points you receive through using it. The order of food does not matter, and I feel this is something that is slowing this program down.



import itertools
import sys
import time

sys.setrecursionlimit(10000000)

#["Name/Carbs/Protein/Fat/Vitamins/Calories"]
available = ['Fiddleheads/3/1/0/3/80', 'Fireweed Shoots/3/0/0/4/150', 'Prickly Pear Fruit/2/1/1/3/190', 'Huckleberries/2/0/0/6/80', 'Rice/7/1/0/0/90', 'Camas Bulb/1/2/5/0/120', 'Beans/1/4/3/0/120', 'Wheat/6/2/0/0/130', 'Crimini Mushrooms/3/3/1/1/200', 'Corn/5/2/0/1/230', 'Beet/3/1/1/3/230', 'Tomato/4/1/0/3/240', 'Raw Fish/0/3/7/0/200', 'Raw Meat/0/7/3/0/250', 'Tallow/0/0/8/0/200', 'Scrap Meat/0/5/5/0/50', 'Prepared Meat/0/4/6/0/600', 'Raw Roast/0/6/5/0/800', 'Raw Sausage/0/4/8/0/500', 'Raw Bacon/0/3/9/0/600', 'Prime Cut/0/9/4/0/600', 'Cereal Germ/5/0/7/3/20', 'Bean Paste/3/5/7/0/40', 'Flour/15/0/0/0/50', 'Sugar/15/0/0/0/50', 'Camas Paste/3/2/10/0/60', 'Cornmeal/9/3/3/0/60', 'Huckleberry Extract/0/0/0/15/60', 'Yeast/0/8/0/7/60', 'Oil/0/0/15/0/120', 'Infused Oil/0/0/12/3/120', 'Simple Syrup/12/0/3/0/400', 'Rice Sludge/10/1/0/2/450', 'Charred Beet/3/0/3/7/470', 'Camas Mash/1/2/9/1/500', 'Campfire Beans/1/9/3/0/500', 'Wilted Fiddleheads/4/1/0/8/500', 'Boiled Shoots/3/0/1/9/510', 'Charred Camas Bulb/2/3/7/1/510', 'Charred Tomato/8/1/0/4/510', 'Charred Corn/8/1/0/4/530', 'Charred Fish/0/9/4/0/550', 'Charred Meat/0/10/10/0/550', 'Wheat Porridge/10/4/0/10/510', 'Charred Sausage/0/11/15/0/500', 'Fried Tomatoes/12/3/9/2/560', 'Bannock/15/3/8/0/600', 'Fiddlehead Salad/6/6/0/14/970', 'Campfire Roast/0/16/12/0/1000', 'Campfire Stew/5/12/9/4/1200', 'Wild Stew/8/5/5/12/1200', 'Fruit Salad/8/2/2/10/900', 'Meat Stock/5/8/9/3/700', 'Vegetable Stock/11/1/2/11/700', 'Camas Bulb Bake/12/7/5/4/400', 'Flatbread/17/8/3/0/500', 'Huckleberry Muffin/10/5/4/11/450', 'Baked Meat/0/13/17/0/600', 'Baked Roast/4/13/8/7/900', 'Huckleberry Pie/9/5/4/16/1300', 'Meat Pie/7/11/11/5/1300', 'Basic Salad/13/6/6/13/800', 'Simmered Meat/6/18/13/5/900', 'Vegetable Medley/9/5/8/20/900', 'Vegetable Soup/12/4/7/19/1200', 'Crispy Bacon/0/18/26/0/600', 'Stuffed Turkey/9/16/12/7/1500']

global AllSP, AllNames
AllSP = []
AllNames = []

def findcombs(totalNames, totalCarbs, totalProtein, totalFat, totalVitamins, totalNutrients, totalCalories, MAXCALORIES):
doneit = False
for each in available:
each = each.split("/")
name = each[0]
carbs = float(each[1])
protein = float(each[2])
fat = float(each[3])
vitamins = float(each[4])
nutrients = carbs+protein+fat+vitamins
calories = float(each[5])
# print(totalNames, totalCalories, calories, each)
if sum(totalCalories)+calories <= MAXCALORIES:
doneit = True
totalNames2 = totalNames[::]
totalCarbs2 = totalCarbs[::]
totalProtein2 = totalProtein[::]
totalFat2 = totalFat[::]
totalVitamins2 = totalVitamins[::]
totalCalories2 = totalCalories[::]
totalNutrients2 = totalNutrients[::]

totalNames2.append(name)
totalCarbs2.append(carbs)
totalProtein2.append(protein)
totalFat2.append(fat)
totalVitamins2.append(vitamins)
totalCalories2.append(calories)
totalNutrients2.append(nutrients)
# print(" ", totalNames2, totalCarbs2, totalProtein2, totalFat2, totalVitamins2, totalNutrients2, totalCalories2)
findcombs(totalNames2, totalCarbs2, totalProtein2, totalFat2, totalVitamins2, totalNutrients2, totalCalories2, MAXCALORIES)
else:
#find SP
try:
carbs = sum([x * y for x, y in zip(totalCalories, totalCarbs)]) / sum(totalCalories)
protein = sum([x * y for x, y in zip(totalCalories, totalProtein)]) / sum(totalCalories)
fat = sum([x * y for x, y in zip(totalCalories, totalFat)]) / sum(totalCalories)
vitamins = sum([x * y for x, y in zip(totalCalories, totalVitamins)]) / sum(totalCalories)
balance = (carbs+protein+fat+vitamins)/(2*max([carbs,protein,fat,vitamins]))
thisSP = sum([x * y for x, y in zip(totalCalories, totalNutrients)]) / sum(totalCalories) * balance + 12
except:
thisSP = 0
#add SP and names to two lists
AllSP.append(thisSP)
AllNames.append(totalNames)

def main(MAXCALORIES):
findcombs([], [], [], [], [], [], [], MAXCALORIES)
index = AllSP.index(max(AllSP))
print()
print(AllSP[index], " ", AllNames[index])

for i in range(100, 3000, 10):
start = time.time()
main(i)
print("Calories:", i, ">>> Time:", time.time()-start)


Edit: On request, here is the formula for calculating the SP



Carbs = (amount1*calories1*carbs1 + ...) / (amount1*calories1 + ...)

(N1*C1) + (N2*C2)
SP = ---------------- x Balance + Base Gain
C1+C2

^^ Where N is the nutrients of the food (carbs+protein+fat+vitamins), and C is the calories of the food

Base Gain = 12 (Always 12)

Balance = Sum Nutrients / (2 * highest nutrition)









share|improve this question









New contributor




Ruler Of The World is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$











  • $begingroup$
    I didn't even know you could set the recursion limit to be so huge... :O Yeah keeping it at 1000 forces you to write safer code btw :)
    $endgroup$
    – Peilonrayz
    3 hours ago










  • $begingroup$
    Good point, when you set it that high it usually means the code is very inefficient! :P @Peilonrayz
    $endgroup$
    – Ruler Of The World
    3 hours ago










  • $begingroup$
    Let's try to be more specific about your constraints. You need to select between 1 and n foods so long as the calorie count is smaller than or equal to 3000? This doesn't need recursion if you use Python's built-in itertools.combinations.
    $endgroup$
    – Reinderien
    2 hours ago










  • $begingroup$
    Can you edit your question to describe the exact mathematical relationship between a set of foods and their computed thisSP value?
    $endgroup$
    – Reinderien
    2 hours ago






  • 1




    $begingroup$
    @greybeard These values are all for a game called "Eco", not for real life!
    $endgroup$
    – Ruler Of The World
    2 hours ago















2












$begingroup$


I've created the following code to try and find the optimum "diet" from a game called Eco. The maximum amount of calories you can have is 3000, as shown with MAXCALORIES.



Is there any way to make this code faster, since the time predicted for this code to compute 3000 calories is well over a few hundred years.



Note: I am trying to find the highest SP (skill points) you get from a diet, the optimum diet. To find this, I must go through every combination of diets and check how many skill points you receive through using it. The order of food does not matter, and I feel this is something that is slowing this program down.



import itertools
import sys
import time

sys.setrecursionlimit(10000000)

#["Name/Carbs/Protein/Fat/Vitamins/Calories"]
available = ['Fiddleheads/3/1/0/3/80', 'Fireweed Shoots/3/0/0/4/150', 'Prickly Pear Fruit/2/1/1/3/190', 'Huckleberries/2/0/0/6/80', 'Rice/7/1/0/0/90', 'Camas Bulb/1/2/5/0/120', 'Beans/1/4/3/0/120', 'Wheat/6/2/0/0/130', 'Crimini Mushrooms/3/3/1/1/200', 'Corn/5/2/0/1/230', 'Beet/3/1/1/3/230', 'Tomato/4/1/0/3/240', 'Raw Fish/0/3/7/0/200', 'Raw Meat/0/7/3/0/250', 'Tallow/0/0/8/0/200', 'Scrap Meat/0/5/5/0/50', 'Prepared Meat/0/4/6/0/600', 'Raw Roast/0/6/5/0/800', 'Raw Sausage/0/4/8/0/500', 'Raw Bacon/0/3/9/0/600', 'Prime Cut/0/9/4/0/600', 'Cereal Germ/5/0/7/3/20', 'Bean Paste/3/5/7/0/40', 'Flour/15/0/0/0/50', 'Sugar/15/0/0/0/50', 'Camas Paste/3/2/10/0/60', 'Cornmeal/9/3/3/0/60', 'Huckleberry Extract/0/0/0/15/60', 'Yeast/0/8/0/7/60', 'Oil/0/0/15/0/120', 'Infused Oil/0/0/12/3/120', 'Simple Syrup/12/0/3/0/400', 'Rice Sludge/10/1/0/2/450', 'Charred Beet/3/0/3/7/470', 'Camas Mash/1/2/9/1/500', 'Campfire Beans/1/9/3/0/500', 'Wilted Fiddleheads/4/1/0/8/500', 'Boiled Shoots/3/0/1/9/510', 'Charred Camas Bulb/2/3/7/1/510', 'Charred Tomato/8/1/0/4/510', 'Charred Corn/8/1/0/4/530', 'Charred Fish/0/9/4/0/550', 'Charred Meat/0/10/10/0/550', 'Wheat Porridge/10/4/0/10/510', 'Charred Sausage/0/11/15/0/500', 'Fried Tomatoes/12/3/9/2/560', 'Bannock/15/3/8/0/600', 'Fiddlehead Salad/6/6/0/14/970', 'Campfire Roast/0/16/12/0/1000', 'Campfire Stew/5/12/9/4/1200', 'Wild Stew/8/5/5/12/1200', 'Fruit Salad/8/2/2/10/900', 'Meat Stock/5/8/9/3/700', 'Vegetable Stock/11/1/2/11/700', 'Camas Bulb Bake/12/7/5/4/400', 'Flatbread/17/8/3/0/500', 'Huckleberry Muffin/10/5/4/11/450', 'Baked Meat/0/13/17/0/600', 'Baked Roast/4/13/8/7/900', 'Huckleberry Pie/9/5/4/16/1300', 'Meat Pie/7/11/11/5/1300', 'Basic Salad/13/6/6/13/800', 'Simmered Meat/6/18/13/5/900', 'Vegetable Medley/9/5/8/20/900', 'Vegetable Soup/12/4/7/19/1200', 'Crispy Bacon/0/18/26/0/600', 'Stuffed Turkey/9/16/12/7/1500']

global AllSP, AllNames
AllSP = []
AllNames = []

def findcombs(totalNames, totalCarbs, totalProtein, totalFat, totalVitamins, totalNutrients, totalCalories, MAXCALORIES):
doneit = False
for each in available:
each = each.split("/")
name = each[0]
carbs = float(each[1])
protein = float(each[2])
fat = float(each[3])
vitamins = float(each[4])
nutrients = carbs+protein+fat+vitamins
calories = float(each[5])
# print(totalNames, totalCalories, calories, each)
if sum(totalCalories)+calories <= MAXCALORIES:
doneit = True
totalNames2 = totalNames[::]
totalCarbs2 = totalCarbs[::]
totalProtein2 = totalProtein[::]
totalFat2 = totalFat[::]
totalVitamins2 = totalVitamins[::]
totalCalories2 = totalCalories[::]
totalNutrients2 = totalNutrients[::]

totalNames2.append(name)
totalCarbs2.append(carbs)
totalProtein2.append(protein)
totalFat2.append(fat)
totalVitamins2.append(vitamins)
totalCalories2.append(calories)
totalNutrients2.append(nutrients)
# print(" ", totalNames2, totalCarbs2, totalProtein2, totalFat2, totalVitamins2, totalNutrients2, totalCalories2)
findcombs(totalNames2, totalCarbs2, totalProtein2, totalFat2, totalVitamins2, totalNutrients2, totalCalories2, MAXCALORIES)
else:
#find SP
try:
carbs = sum([x * y for x, y in zip(totalCalories, totalCarbs)]) / sum(totalCalories)
protein = sum([x * y for x, y in zip(totalCalories, totalProtein)]) / sum(totalCalories)
fat = sum([x * y for x, y in zip(totalCalories, totalFat)]) / sum(totalCalories)
vitamins = sum([x * y for x, y in zip(totalCalories, totalVitamins)]) / sum(totalCalories)
balance = (carbs+protein+fat+vitamins)/(2*max([carbs,protein,fat,vitamins]))
thisSP = sum([x * y for x, y in zip(totalCalories, totalNutrients)]) / sum(totalCalories) * balance + 12
except:
thisSP = 0
#add SP and names to two lists
AllSP.append(thisSP)
AllNames.append(totalNames)

def main(MAXCALORIES):
findcombs([], [], [], [], [], [], [], MAXCALORIES)
index = AllSP.index(max(AllSP))
print()
print(AllSP[index], " ", AllNames[index])

for i in range(100, 3000, 10):
start = time.time()
main(i)
print("Calories:", i, ">>> Time:", time.time()-start)


Edit: On request, here is the formula for calculating the SP



Carbs = (amount1*calories1*carbs1 + ...) / (amount1*calories1 + ...)

(N1*C1) + (N2*C2)
SP = ---------------- x Balance + Base Gain
C1+C2

^^ Where N is the nutrients of the food (carbs+protein+fat+vitamins), and C is the calories of the food

Base Gain = 12 (Always 12)

Balance = Sum Nutrients / (2 * highest nutrition)









share|improve this question









New contributor




Ruler Of The World is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$











  • $begingroup$
    I didn't even know you could set the recursion limit to be so huge... :O Yeah keeping it at 1000 forces you to write safer code btw :)
    $endgroup$
    – Peilonrayz
    3 hours ago










  • $begingroup$
    Good point, when you set it that high it usually means the code is very inefficient! :P @Peilonrayz
    $endgroup$
    – Ruler Of The World
    3 hours ago










  • $begingroup$
    Let's try to be more specific about your constraints. You need to select between 1 and n foods so long as the calorie count is smaller than or equal to 3000? This doesn't need recursion if you use Python's built-in itertools.combinations.
    $endgroup$
    – Reinderien
    2 hours ago










  • $begingroup$
    Can you edit your question to describe the exact mathematical relationship between a set of foods and their computed thisSP value?
    $endgroup$
    – Reinderien
    2 hours ago






  • 1




    $begingroup$
    @greybeard These values are all for a game called "Eco", not for real life!
    $endgroup$
    – Ruler Of The World
    2 hours ago













2












2








2





$begingroup$


I've created the following code to try and find the optimum "diet" from a game called Eco. The maximum amount of calories you can have is 3000, as shown with MAXCALORIES.



Is there any way to make this code faster, since the time predicted for this code to compute 3000 calories is well over a few hundred years.



Note: I am trying to find the highest SP (skill points) you get from a diet, the optimum diet. To find this, I must go through every combination of diets and check how many skill points you receive through using it. The order of food does not matter, and I feel this is something that is slowing this program down.



import itertools
import sys
import time

sys.setrecursionlimit(10000000)

#["Name/Carbs/Protein/Fat/Vitamins/Calories"]
available = ['Fiddleheads/3/1/0/3/80', 'Fireweed Shoots/3/0/0/4/150', 'Prickly Pear Fruit/2/1/1/3/190', 'Huckleberries/2/0/0/6/80', 'Rice/7/1/0/0/90', 'Camas Bulb/1/2/5/0/120', 'Beans/1/4/3/0/120', 'Wheat/6/2/0/0/130', 'Crimini Mushrooms/3/3/1/1/200', 'Corn/5/2/0/1/230', 'Beet/3/1/1/3/230', 'Tomato/4/1/0/3/240', 'Raw Fish/0/3/7/0/200', 'Raw Meat/0/7/3/0/250', 'Tallow/0/0/8/0/200', 'Scrap Meat/0/5/5/0/50', 'Prepared Meat/0/4/6/0/600', 'Raw Roast/0/6/5/0/800', 'Raw Sausage/0/4/8/0/500', 'Raw Bacon/0/3/9/0/600', 'Prime Cut/0/9/4/0/600', 'Cereal Germ/5/0/7/3/20', 'Bean Paste/3/5/7/0/40', 'Flour/15/0/0/0/50', 'Sugar/15/0/0/0/50', 'Camas Paste/3/2/10/0/60', 'Cornmeal/9/3/3/0/60', 'Huckleberry Extract/0/0/0/15/60', 'Yeast/0/8/0/7/60', 'Oil/0/0/15/0/120', 'Infused Oil/0/0/12/3/120', 'Simple Syrup/12/0/3/0/400', 'Rice Sludge/10/1/0/2/450', 'Charred Beet/3/0/3/7/470', 'Camas Mash/1/2/9/1/500', 'Campfire Beans/1/9/3/0/500', 'Wilted Fiddleheads/4/1/0/8/500', 'Boiled Shoots/3/0/1/9/510', 'Charred Camas Bulb/2/3/7/1/510', 'Charred Tomato/8/1/0/4/510', 'Charred Corn/8/1/0/4/530', 'Charred Fish/0/9/4/0/550', 'Charred Meat/0/10/10/0/550', 'Wheat Porridge/10/4/0/10/510', 'Charred Sausage/0/11/15/0/500', 'Fried Tomatoes/12/3/9/2/560', 'Bannock/15/3/8/0/600', 'Fiddlehead Salad/6/6/0/14/970', 'Campfire Roast/0/16/12/0/1000', 'Campfire Stew/5/12/9/4/1200', 'Wild Stew/8/5/5/12/1200', 'Fruit Salad/8/2/2/10/900', 'Meat Stock/5/8/9/3/700', 'Vegetable Stock/11/1/2/11/700', 'Camas Bulb Bake/12/7/5/4/400', 'Flatbread/17/8/3/0/500', 'Huckleberry Muffin/10/5/4/11/450', 'Baked Meat/0/13/17/0/600', 'Baked Roast/4/13/8/7/900', 'Huckleberry Pie/9/5/4/16/1300', 'Meat Pie/7/11/11/5/1300', 'Basic Salad/13/6/6/13/800', 'Simmered Meat/6/18/13/5/900', 'Vegetable Medley/9/5/8/20/900', 'Vegetable Soup/12/4/7/19/1200', 'Crispy Bacon/0/18/26/0/600', 'Stuffed Turkey/9/16/12/7/1500']

global AllSP, AllNames
AllSP = []
AllNames = []

def findcombs(totalNames, totalCarbs, totalProtein, totalFat, totalVitamins, totalNutrients, totalCalories, MAXCALORIES):
doneit = False
for each in available:
each = each.split("/")
name = each[0]
carbs = float(each[1])
protein = float(each[2])
fat = float(each[3])
vitamins = float(each[4])
nutrients = carbs+protein+fat+vitamins
calories = float(each[5])
# print(totalNames, totalCalories, calories, each)
if sum(totalCalories)+calories <= MAXCALORIES:
doneit = True
totalNames2 = totalNames[::]
totalCarbs2 = totalCarbs[::]
totalProtein2 = totalProtein[::]
totalFat2 = totalFat[::]
totalVitamins2 = totalVitamins[::]
totalCalories2 = totalCalories[::]
totalNutrients2 = totalNutrients[::]

totalNames2.append(name)
totalCarbs2.append(carbs)
totalProtein2.append(protein)
totalFat2.append(fat)
totalVitamins2.append(vitamins)
totalCalories2.append(calories)
totalNutrients2.append(nutrients)
# print(" ", totalNames2, totalCarbs2, totalProtein2, totalFat2, totalVitamins2, totalNutrients2, totalCalories2)
findcombs(totalNames2, totalCarbs2, totalProtein2, totalFat2, totalVitamins2, totalNutrients2, totalCalories2, MAXCALORIES)
else:
#find SP
try:
carbs = sum([x * y for x, y in zip(totalCalories, totalCarbs)]) / sum(totalCalories)
protein = sum([x * y for x, y in zip(totalCalories, totalProtein)]) / sum(totalCalories)
fat = sum([x * y for x, y in zip(totalCalories, totalFat)]) / sum(totalCalories)
vitamins = sum([x * y for x, y in zip(totalCalories, totalVitamins)]) / sum(totalCalories)
balance = (carbs+protein+fat+vitamins)/(2*max([carbs,protein,fat,vitamins]))
thisSP = sum([x * y for x, y in zip(totalCalories, totalNutrients)]) / sum(totalCalories) * balance + 12
except:
thisSP = 0
#add SP and names to two lists
AllSP.append(thisSP)
AllNames.append(totalNames)

def main(MAXCALORIES):
findcombs([], [], [], [], [], [], [], MAXCALORIES)
index = AllSP.index(max(AllSP))
print()
print(AllSP[index], " ", AllNames[index])

for i in range(100, 3000, 10):
start = time.time()
main(i)
print("Calories:", i, ">>> Time:", time.time()-start)


Edit: On request, here is the formula for calculating the SP



Carbs = (amount1*calories1*carbs1 + ...) / (amount1*calories1 + ...)

(N1*C1) + (N2*C2)
SP = ---------------- x Balance + Base Gain
C1+C2

^^ Where N is the nutrients of the food (carbs+protein+fat+vitamins), and C is the calories of the food

Base Gain = 12 (Always 12)

Balance = Sum Nutrients / (2 * highest nutrition)









share|improve this question









New contributor




Ruler Of The World is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$




I've created the following code to try and find the optimum "diet" from a game called Eco. The maximum amount of calories you can have is 3000, as shown with MAXCALORIES.



Is there any way to make this code faster, since the time predicted for this code to compute 3000 calories is well over a few hundred years.



Note: I am trying to find the highest SP (skill points) you get from a diet, the optimum diet. To find this, I must go through every combination of diets and check how many skill points you receive through using it. The order of food does not matter, and I feel this is something that is slowing this program down.



import itertools
import sys
import time

sys.setrecursionlimit(10000000)

#["Name/Carbs/Protein/Fat/Vitamins/Calories"]
available = ['Fiddleheads/3/1/0/3/80', 'Fireweed Shoots/3/0/0/4/150', 'Prickly Pear Fruit/2/1/1/3/190', 'Huckleberries/2/0/0/6/80', 'Rice/7/1/0/0/90', 'Camas Bulb/1/2/5/0/120', 'Beans/1/4/3/0/120', 'Wheat/6/2/0/0/130', 'Crimini Mushrooms/3/3/1/1/200', 'Corn/5/2/0/1/230', 'Beet/3/1/1/3/230', 'Tomato/4/1/0/3/240', 'Raw Fish/0/3/7/0/200', 'Raw Meat/0/7/3/0/250', 'Tallow/0/0/8/0/200', 'Scrap Meat/0/5/5/0/50', 'Prepared Meat/0/4/6/0/600', 'Raw Roast/0/6/5/0/800', 'Raw Sausage/0/4/8/0/500', 'Raw Bacon/0/3/9/0/600', 'Prime Cut/0/9/4/0/600', 'Cereal Germ/5/0/7/3/20', 'Bean Paste/3/5/7/0/40', 'Flour/15/0/0/0/50', 'Sugar/15/0/0/0/50', 'Camas Paste/3/2/10/0/60', 'Cornmeal/9/3/3/0/60', 'Huckleberry Extract/0/0/0/15/60', 'Yeast/0/8/0/7/60', 'Oil/0/0/15/0/120', 'Infused Oil/0/0/12/3/120', 'Simple Syrup/12/0/3/0/400', 'Rice Sludge/10/1/0/2/450', 'Charred Beet/3/0/3/7/470', 'Camas Mash/1/2/9/1/500', 'Campfire Beans/1/9/3/0/500', 'Wilted Fiddleheads/4/1/0/8/500', 'Boiled Shoots/3/0/1/9/510', 'Charred Camas Bulb/2/3/7/1/510', 'Charred Tomato/8/1/0/4/510', 'Charred Corn/8/1/0/4/530', 'Charred Fish/0/9/4/0/550', 'Charred Meat/0/10/10/0/550', 'Wheat Porridge/10/4/0/10/510', 'Charred Sausage/0/11/15/0/500', 'Fried Tomatoes/12/3/9/2/560', 'Bannock/15/3/8/0/600', 'Fiddlehead Salad/6/6/0/14/970', 'Campfire Roast/0/16/12/0/1000', 'Campfire Stew/5/12/9/4/1200', 'Wild Stew/8/5/5/12/1200', 'Fruit Salad/8/2/2/10/900', 'Meat Stock/5/8/9/3/700', 'Vegetable Stock/11/1/2/11/700', 'Camas Bulb Bake/12/7/5/4/400', 'Flatbread/17/8/3/0/500', 'Huckleberry Muffin/10/5/4/11/450', 'Baked Meat/0/13/17/0/600', 'Baked Roast/4/13/8/7/900', 'Huckleberry Pie/9/5/4/16/1300', 'Meat Pie/7/11/11/5/1300', 'Basic Salad/13/6/6/13/800', 'Simmered Meat/6/18/13/5/900', 'Vegetable Medley/9/5/8/20/900', 'Vegetable Soup/12/4/7/19/1200', 'Crispy Bacon/0/18/26/0/600', 'Stuffed Turkey/9/16/12/7/1500']

global AllSP, AllNames
AllSP = []
AllNames = []

def findcombs(totalNames, totalCarbs, totalProtein, totalFat, totalVitamins, totalNutrients, totalCalories, MAXCALORIES):
doneit = False
for each in available:
each = each.split("/")
name = each[0]
carbs = float(each[1])
protein = float(each[2])
fat = float(each[3])
vitamins = float(each[4])
nutrients = carbs+protein+fat+vitamins
calories = float(each[5])
# print(totalNames, totalCalories, calories, each)
if sum(totalCalories)+calories <= MAXCALORIES:
doneit = True
totalNames2 = totalNames[::]
totalCarbs2 = totalCarbs[::]
totalProtein2 = totalProtein[::]
totalFat2 = totalFat[::]
totalVitamins2 = totalVitamins[::]
totalCalories2 = totalCalories[::]
totalNutrients2 = totalNutrients[::]

totalNames2.append(name)
totalCarbs2.append(carbs)
totalProtein2.append(protein)
totalFat2.append(fat)
totalVitamins2.append(vitamins)
totalCalories2.append(calories)
totalNutrients2.append(nutrients)
# print(" ", totalNames2, totalCarbs2, totalProtein2, totalFat2, totalVitamins2, totalNutrients2, totalCalories2)
findcombs(totalNames2, totalCarbs2, totalProtein2, totalFat2, totalVitamins2, totalNutrients2, totalCalories2, MAXCALORIES)
else:
#find SP
try:
carbs = sum([x * y for x, y in zip(totalCalories, totalCarbs)]) / sum(totalCalories)
protein = sum([x * y for x, y in zip(totalCalories, totalProtein)]) / sum(totalCalories)
fat = sum([x * y for x, y in zip(totalCalories, totalFat)]) / sum(totalCalories)
vitamins = sum([x * y for x, y in zip(totalCalories, totalVitamins)]) / sum(totalCalories)
balance = (carbs+protein+fat+vitamins)/(2*max([carbs,protein,fat,vitamins]))
thisSP = sum([x * y for x, y in zip(totalCalories, totalNutrients)]) / sum(totalCalories) * balance + 12
except:
thisSP = 0
#add SP and names to two lists
AllSP.append(thisSP)
AllNames.append(totalNames)

def main(MAXCALORIES):
findcombs([], [], [], [], [], [], [], MAXCALORIES)
index = AllSP.index(max(AllSP))
print()
print(AllSP[index], " ", AllNames[index])

for i in range(100, 3000, 10):
start = time.time()
main(i)
print("Calories:", i, ">>> Time:", time.time()-start)


Edit: On request, here is the formula for calculating the SP



Carbs = (amount1*calories1*carbs1 + ...) / (amount1*calories1 + ...)

(N1*C1) + (N2*C2)
SP = ---------------- x Balance + Base Gain
C1+C2

^^ Where N is the nutrients of the food (carbs+protein+fat+vitamins), and C is the calories of the food

Base Gain = 12 (Always 12)

Balance = Sum Nutrients / (2 * highest nutrition)






python performance python-3.x






share|improve this question









New contributor




Ruler Of The World is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Ruler Of The World is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 2 hours ago







Ruler Of The World













New contributor




Ruler Of The World is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 3 hours ago









Ruler Of The WorldRuler Of The World

1115




1115




New contributor




Ruler Of The World is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Ruler Of The World is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Ruler Of The World is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











  • $begingroup$
    I didn't even know you could set the recursion limit to be so huge... :O Yeah keeping it at 1000 forces you to write safer code btw :)
    $endgroup$
    – Peilonrayz
    3 hours ago










  • $begingroup$
    Good point, when you set it that high it usually means the code is very inefficient! :P @Peilonrayz
    $endgroup$
    – Ruler Of The World
    3 hours ago










  • $begingroup$
    Let's try to be more specific about your constraints. You need to select between 1 and n foods so long as the calorie count is smaller than or equal to 3000? This doesn't need recursion if you use Python's built-in itertools.combinations.
    $endgroup$
    – Reinderien
    2 hours ago










  • $begingroup$
    Can you edit your question to describe the exact mathematical relationship between a set of foods and their computed thisSP value?
    $endgroup$
    – Reinderien
    2 hours ago






  • 1




    $begingroup$
    @greybeard These values are all for a game called "Eco", not for real life!
    $endgroup$
    – Ruler Of The World
    2 hours ago
















  • $begingroup$
    I didn't even know you could set the recursion limit to be so huge... :O Yeah keeping it at 1000 forces you to write safer code btw :)
    $endgroup$
    – Peilonrayz
    3 hours ago










  • $begingroup$
    Good point, when you set it that high it usually means the code is very inefficient! :P @Peilonrayz
    $endgroup$
    – Ruler Of The World
    3 hours ago










  • $begingroup$
    Let's try to be more specific about your constraints. You need to select between 1 and n foods so long as the calorie count is smaller than or equal to 3000? This doesn't need recursion if you use Python's built-in itertools.combinations.
    $endgroup$
    – Reinderien
    2 hours ago










  • $begingroup$
    Can you edit your question to describe the exact mathematical relationship between a set of foods and their computed thisSP value?
    $endgroup$
    – Reinderien
    2 hours ago






  • 1




    $begingroup$
    @greybeard These values are all for a game called "Eco", not for real life!
    $endgroup$
    – Ruler Of The World
    2 hours ago















$begingroup$
I didn't even know you could set the recursion limit to be so huge... :O Yeah keeping it at 1000 forces you to write safer code btw :)
$endgroup$
– Peilonrayz
3 hours ago




$begingroup$
I didn't even know you could set the recursion limit to be so huge... :O Yeah keeping it at 1000 forces you to write safer code btw :)
$endgroup$
– Peilonrayz
3 hours ago












$begingroup$
Good point, when you set it that high it usually means the code is very inefficient! :P @Peilonrayz
$endgroup$
– Ruler Of The World
3 hours ago




$begingroup$
Good point, when you set it that high it usually means the code is very inefficient! :P @Peilonrayz
$endgroup$
– Ruler Of The World
3 hours ago












$begingroup$
Let's try to be more specific about your constraints. You need to select between 1 and n foods so long as the calorie count is smaller than or equal to 3000? This doesn't need recursion if you use Python's built-in itertools.combinations.
$endgroup$
– Reinderien
2 hours ago




$begingroup$
Let's try to be more specific about your constraints. You need to select between 1 and n foods so long as the calorie count is smaller than or equal to 3000? This doesn't need recursion if you use Python's built-in itertools.combinations.
$endgroup$
– Reinderien
2 hours ago












$begingroup$
Can you edit your question to describe the exact mathematical relationship between a set of foods and their computed thisSP value?
$endgroup$
– Reinderien
2 hours ago




$begingroup$
Can you edit your question to describe the exact mathematical relationship between a set of foods and their computed thisSP value?
$endgroup$
– Reinderien
2 hours ago




1




1




$begingroup$
@greybeard These values are all for a game called "Eco", not for real life!
$endgroup$
– Ruler Of The World
2 hours ago




$begingroup$
@greybeard These values are all for a game called "Eco", not for real life!
$endgroup$
– Ruler Of The World
2 hours ago










2 Answers
2






active

oldest

votes


















3












$begingroup$


  1. Global variables are bad. Don't use them. I have to spend a long while looking at your code to tell what uses them and when. When your code becomes hundreds of lines long this is tedious and unmaintainable.



    If you need to use recursion and add to something not in the recursive function use a closure.



  2. You should load available into an object, rather than extract the information from it each and every time you use it.


  3. Using the above you can simplify all your totalNames, totalCarbs into one list.

  4. Rather than using AllSP and AllNames you can add a tuple to one list.

  5. You should put all your code into a main so that you reduce the amount of variables in the global scope. This goes hand in hand with (1).

  6. Rather than copying and pasting the same line multiple times you can create a function.

All this gets the following. Which should be easier for you to increase the performance from:



import itertools
import sys
import time
import collections

sys.setrecursionlimit(10000000)

_Food = collections.namedtuple('Food', 'name carbs protein fat vitamins calories')

class Food(_Food):
@property
def nutrients(self):
return sum(self[1:5])


def read_foods(foods):
for food in foods:
name, *other = food.split('/')
yield Food(name, *[float(v) for v in other])


def tot_avg(food, attr):
return (
sum(f.calories * getattr(f, attr) for f in food)
/ sum(f.calories for f in food)
)


def find_combs(available, MAXCALORIES):
all_combinations = []
def inner(total):
for food in available:
total_calories = [f.calories for f in total]
if sum(total_calories) + food.calories <= MAXCALORIES:
inner(total[:] + [food], MAXCALORIES)
else:
nutrients = [
tot_avg(total, 'carbs'),
tot_avg(total, 'protein'),
tot_avg(total, 'fat'),
tot_avg(total, 'vitamins')
]
balance = sum(nutrients) / 2 / max(nutrients)
sp = tot_avg(total, 'nutrients') * balance + 12
all_combinations.append((sp, total))
inner([])
return all_combinations


def main(available):
for MAXCALORIES in range(100, 3000, 10):
start = time.time()
all_ = findcombs(available, MAXCALORIES)
amount, foods = max(all_, key=lambda i: i[0])
print(amount, ' ', [f.name for f in foods])
print('Calories:', i, '>>> Time:', time.time()-start)


if __name__ == '__main__':
available = ['Fiddleheads/3/1/0/3/80', 'Fireweed Shoots/3/0/0/4/150', 'Prickly Pear Fruit/2/1/1/3/190', 'Huckleberries/2/0/0/6/80', 'Rice/7/1/0/0/90', 'Camas Bulb/1/2/5/0/120', 'Beans/1/4/3/0/120', 'Wheat/6/2/0/0/130', 'Crimini Mushrooms/3/3/1/1/200', 'Corn/5/2/0/1/230', 'Beet/3/1/1/3/230', 'Tomato/4/1/0/3/240', 'Raw Fish/0/3/7/0/200', 'Raw Meat/0/7/3/0/250', 'Tallow/0/0/8/0/200', 'Scrap Meat/0/5/5/0/50', 'Prepared Meat/0/4/6/0/600', 'Raw Roast/0/6/5/0/800', 'Raw Sausage/0/4/8/0/500', 'Raw Bacon/0/3/9/0/600', 'Prime Cut/0/9/4/0/600', 'Cereal Germ/5/0/7/3/20', 'Bean Paste/3/5/7/0/40', 'Flour/15/0/0/0/50', 'Sugar/15/0/0/0/50', 'Camas Paste/3/2/10/0/60', 'Cornmeal/9/3/3/0/60', 'Huckleberry Extract/0/0/0/15/60', 'Yeast/0/8/0/7/60', 'Oil/0/0/15/0/120', 'Infused Oil/0/0/12/3/120', 'Simple Syrup/12/0/3/0/400', 'Rice Sludge/10/1/0/2/450', 'Charred Beet/3/0/3/7/470', 'Camas Mash/1/2/9/1/500', 'Campfire Beans/1/9/3/0/500', 'Wilted Fiddleheads/4/1/0/8/500', 'Boiled Shoots/3/0/1/9/510', 'Charred Camas Bulb/2/3/7/1/510', 'Charred Tomato/8/1/0/4/510', 'Charred Corn/8/1/0/4/530', 'Charred Fish/0/9/4/0/550', 'Charred Meat/0/10/10/0/550', 'Wheat Porridge/10/4/0/10/510', 'Charred Sausage/0/11/15/0/500', 'Fried Tomatoes/12/3/9/2/560', 'Bannock/15/3/8/0/600', 'Fiddlehead Salad/6/6/0/14/970', 'Campfire Roast/0/16/12/0/1000', 'Campfire Stew/5/12/9/4/1200', 'Wild Stew/8/5/5/12/1200', 'Fruit Salad/8/2/2/10/900', 'Meat Stock/5/8/9/3/700', 'Vegetable Stock/11/1/2/11/700', 'Camas Bulb Bake/12/7/5/4/400', 'Flatbread/17/8/3/0/500', 'Huckleberry Muffin/10/5/4/11/450', 'Baked Meat/0/13/17/0/600', 'Baked Roast/4/13/8/7/900', 'Huckleberry Pie/9/5/4/16/1300', 'Meat Pie/7/11/11/5/1300', 'Basic Salad/13/6/6/13/800', 'Simmered Meat/6/18/13/5/900', 'Vegetable Medley/9/5/8/20/900', 'Vegetable Soup/12/4/7/19/1200', 'Crispy Bacon/0/18/26/0/600', 'Stuffed Turkey/9/16/12/7/1500']
main(list(read_foods(available)))





share|improve this answer









$endgroup$




















    2












    $begingroup$

    Data representation



    Your choice of data representation is curious. It's a middle ground between a fully-serialized text format and a fully-deserialized in-memory format (such as nested tuples or dictionaries). I'd offer that it's not as good as either of the above. If you're going for micro-optimization, you need to do "pre-deserialized" literal variable initialization that doesn't require parsing at all. The best option would probably be named tuples or even plain tuples, i.e.



    available = (
    ('Fiddleheads', 3, 1, 0, 3, 80),
    # ...
    )


    But this won't yield any noticeable benefit, and it's not as maintainable as the alternative: just write a CSV file.



    main isn't main



    You've written a main function that isn't actually top-level code. This is not advisable. Rename it to something else, and put your top-level code in an actual main function, called from global scope with a standard if __name__ == '__main__' check.



    list duplication



    This:



    totalNames[::]


    should simply be



    list(totalNames)


    snake_case



    Your names should follow the format total_names, rather than totalNames.



    Also, variables in global scope (i.e. AllSP) should be all-caps; and you shouldn't need to declare them global.



    I'm going to do some reading and see what you're doing in terms of algorithm and submit a second answer to suggest a saner one.






    share|improve this answer









    $endgroup$












    • $begingroup$
      Wow, thanks a lot! I'll edit my code following your advice now. Let me know if you find a way to optimise the algorithm!
      $endgroup$
      – Ruler Of The World
      3 hours ago










    • $begingroup$
      @RulerOfTheWorld Please do not edit the code in your question once reviewing started.
      $endgroup$
      – greybeard
      2 hours ago











    • $begingroup$
      @greybeard Of course, my apologies. I was not editing the code, but explaining the functions behind it in a section marked as an edit at the end of my post, so it wouldn't affect the previous code.
      $endgroup$
      – Ruler Of The World
      2 hours ago











    Your Answer





    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );






    Ruler Of The World is a new contributor. Be nice, and check out our Code of Conduct.









    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f215626%2foptimising-a-list-searching-algorithm%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3












    $begingroup$


    1. Global variables are bad. Don't use them. I have to spend a long while looking at your code to tell what uses them and when. When your code becomes hundreds of lines long this is tedious and unmaintainable.



      If you need to use recursion and add to something not in the recursive function use a closure.



    2. You should load available into an object, rather than extract the information from it each and every time you use it.


    3. Using the above you can simplify all your totalNames, totalCarbs into one list.

    4. Rather than using AllSP and AllNames you can add a tuple to one list.

    5. You should put all your code into a main so that you reduce the amount of variables in the global scope. This goes hand in hand with (1).

    6. Rather than copying and pasting the same line multiple times you can create a function.

    All this gets the following. Which should be easier for you to increase the performance from:



    import itertools
    import sys
    import time
    import collections

    sys.setrecursionlimit(10000000)

    _Food = collections.namedtuple('Food', 'name carbs protein fat vitamins calories')

    class Food(_Food):
    @property
    def nutrients(self):
    return sum(self[1:5])


    def read_foods(foods):
    for food in foods:
    name, *other = food.split('/')
    yield Food(name, *[float(v) for v in other])


    def tot_avg(food, attr):
    return (
    sum(f.calories * getattr(f, attr) for f in food)
    / sum(f.calories for f in food)
    )


    def find_combs(available, MAXCALORIES):
    all_combinations = []
    def inner(total):
    for food in available:
    total_calories = [f.calories for f in total]
    if sum(total_calories) + food.calories <= MAXCALORIES:
    inner(total[:] + [food], MAXCALORIES)
    else:
    nutrients = [
    tot_avg(total, 'carbs'),
    tot_avg(total, 'protein'),
    tot_avg(total, 'fat'),
    tot_avg(total, 'vitamins')
    ]
    balance = sum(nutrients) / 2 / max(nutrients)
    sp = tot_avg(total, 'nutrients') * balance + 12
    all_combinations.append((sp, total))
    inner([])
    return all_combinations


    def main(available):
    for MAXCALORIES in range(100, 3000, 10):
    start = time.time()
    all_ = findcombs(available, MAXCALORIES)
    amount, foods = max(all_, key=lambda i: i[0])
    print(amount, ' ', [f.name for f in foods])
    print('Calories:', i, '>>> Time:', time.time()-start)


    if __name__ == '__main__':
    available = ['Fiddleheads/3/1/0/3/80', 'Fireweed Shoots/3/0/0/4/150', 'Prickly Pear Fruit/2/1/1/3/190', 'Huckleberries/2/0/0/6/80', 'Rice/7/1/0/0/90', 'Camas Bulb/1/2/5/0/120', 'Beans/1/4/3/0/120', 'Wheat/6/2/0/0/130', 'Crimini Mushrooms/3/3/1/1/200', 'Corn/5/2/0/1/230', 'Beet/3/1/1/3/230', 'Tomato/4/1/0/3/240', 'Raw Fish/0/3/7/0/200', 'Raw Meat/0/7/3/0/250', 'Tallow/0/0/8/0/200', 'Scrap Meat/0/5/5/0/50', 'Prepared Meat/0/4/6/0/600', 'Raw Roast/0/6/5/0/800', 'Raw Sausage/0/4/8/0/500', 'Raw Bacon/0/3/9/0/600', 'Prime Cut/0/9/4/0/600', 'Cereal Germ/5/0/7/3/20', 'Bean Paste/3/5/7/0/40', 'Flour/15/0/0/0/50', 'Sugar/15/0/0/0/50', 'Camas Paste/3/2/10/0/60', 'Cornmeal/9/3/3/0/60', 'Huckleberry Extract/0/0/0/15/60', 'Yeast/0/8/0/7/60', 'Oil/0/0/15/0/120', 'Infused Oil/0/0/12/3/120', 'Simple Syrup/12/0/3/0/400', 'Rice Sludge/10/1/0/2/450', 'Charred Beet/3/0/3/7/470', 'Camas Mash/1/2/9/1/500', 'Campfire Beans/1/9/3/0/500', 'Wilted Fiddleheads/4/1/0/8/500', 'Boiled Shoots/3/0/1/9/510', 'Charred Camas Bulb/2/3/7/1/510', 'Charred Tomato/8/1/0/4/510', 'Charred Corn/8/1/0/4/530', 'Charred Fish/0/9/4/0/550', 'Charred Meat/0/10/10/0/550', 'Wheat Porridge/10/4/0/10/510', 'Charred Sausage/0/11/15/0/500', 'Fried Tomatoes/12/3/9/2/560', 'Bannock/15/3/8/0/600', 'Fiddlehead Salad/6/6/0/14/970', 'Campfire Roast/0/16/12/0/1000', 'Campfire Stew/5/12/9/4/1200', 'Wild Stew/8/5/5/12/1200', 'Fruit Salad/8/2/2/10/900', 'Meat Stock/5/8/9/3/700', 'Vegetable Stock/11/1/2/11/700', 'Camas Bulb Bake/12/7/5/4/400', 'Flatbread/17/8/3/0/500', 'Huckleberry Muffin/10/5/4/11/450', 'Baked Meat/0/13/17/0/600', 'Baked Roast/4/13/8/7/900', 'Huckleberry Pie/9/5/4/16/1300', 'Meat Pie/7/11/11/5/1300', 'Basic Salad/13/6/6/13/800', 'Simmered Meat/6/18/13/5/900', 'Vegetable Medley/9/5/8/20/900', 'Vegetable Soup/12/4/7/19/1200', 'Crispy Bacon/0/18/26/0/600', 'Stuffed Turkey/9/16/12/7/1500']
    main(list(read_foods(available)))





    share|improve this answer









    $endgroup$

















      3












      $begingroup$


      1. Global variables are bad. Don't use them. I have to spend a long while looking at your code to tell what uses them and when. When your code becomes hundreds of lines long this is tedious and unmaintainable.



        If you need to use recursion and add to something not in the recursive function use a closure.



      2. You should load available into an object, rather than extract the information from it each and every time you use it.


      3. Using the above you can simplify all your totalNames, totalCarbs into one list.

      4. Rather than using AllSP and AllNames you can add a tuple to one list.

      5. You should put all your code into a main so that you reduce the amount of variables in the global scope. This goes hand in hand with (1).

      6. Rather than copying and pasting the same line multiple times you can create a function.

      All this gets the following. Which should be easier for you to increase the performance from:



      import itertools
      import sys
      import time
      import collections

      sys.setrecursionlimit(10000000)

      _Food = collections.namedtuple('Food', 'name carbs protein fat vitamins calories')

      class Food(_Food):
      @property
      def nutrients(self):
      return sum(self[1:5])


      def read_foods(foods):
      for food in foods:
      name, *other = food.split('/')
      yield Food(name, *[float(v) for v in other])


      def tot_avg(food, attr):
      return (
      sum(f.calories * getattr(f, attr) for f in food)
      / sum(f.calories for f in food)
      )


      def find_combs(available, MAXCALORIES):
      all_combinations = []
      def inner(total):
      for food in available:
      total_calories = [f.calories for f in total]
      if sum(total_calories) + food.calories <= MAXCALORIES:
      inner(total[:] + [food], MAXCALORIES)
      else:
      nutrients = [
      tot_avg(total, 'carbs'),
      tot_avg(total, 'protein'),
      tot_avg(total, 'fat'),
      tot_avg(total, 'vitamins')
      ]
      balance = sum(nutrients) / 2 / max(nutrients)
      sp = tot_avg(total, 'nutrients') * balance + 12
      all_combinations.append((sp, total))
      inner([])
      return all_combinations


      def main(available):
      for MAXCALORIES in range(100, 3000, 10):
      start = time.time()
      all_ = findcombs(available, MAXCALORIES)
      amount, foods = max(all_, key=lambda i: i[0])
      print(amount, ' ', [f.name for f in foods])
      print('Calories:', i, '>>> Time:', time.time()-start)


      if __name__ == '__main__':
      available = ['Fiddleheads/3/1/0/3/80', 'Fireweed Shoots/3/0/0/4/150', 'Prickly Pear Fruit/2/1/1/3/190', 'Huckleberries/2/0/0/6/80', 'Rice/7/1/0/0/90', 'Camas Bulb/1/2/5/0/120', 'Beans/1/4/3/0/120', 'Wheat/6/2/0/0/130', 'Crimini Mushrooms/3/3/1/1/200', 'Corn/5/2/0/1/230', 'Beet/3/1/1/3/230', 'Tomato/4/1/0/3/240', 'Raw Fish/0/3/7/0/200', 'Raw Meat/0/7/3/0/250', 'Tallow/0/0/8/0/200', 'Scrap Meat/0/5/5/0/50', 'Prepared Meat/0/4/6/0/600', 'Raw Roast/0/6/5/0/800', 'Raw Sausage/0/4/8/0/500', 'Raw Bacon/0/3/9/0/600', 'Prime Cut/0/9/4/0/600', 'Cereal Germ/5/0/7/3/20', 'Bean Paste/3/5/7/0/40', 'Flour/15/0/0/0/50', 'Sugar/15/0/0/0/50', 'Camas Paste/3/2/10/0/60', 'Cornmeal/9/3/3/0/60', 'Huckleberry Extract/0/0/0/15/60', 'Yeast/0/8/0/7/60', 'Oil/0/0/15/0/120', 'Infused Oil/0/0/12/3/120', 'Simple Syrup/12/0/3/0/400', 'Rice Sludge/10/1/0/2/450', 'Charred Beet/3/0/3/7/470', 'Camas Mash/1/2/9/1/500', 'Campfire Beans/1/9/3/0/500', 'Wilted Fiddleheads/4/1/0/8/500', 'Boiled Shoots/3/0/1/9/510', 'Charred Camas Bulb/2/3/7/1/510', 'Charred Tomato/8/1/0/4/510', 'Charred Corn/8/1/0/4/530', 'Charred Fish/0/9/4/0/550', 'Charred Meat/0/10/10/0/550', 'Wheat Porridge/10/4/0/10/510', 'Charred Sausage/0/11/15/0/500', 'Fried Tomatoes/12/3/9/2/560', 'Bannock/15/3/8/0/600', 'Fiddlehead Salad/6/6/0/14/970', 'Campfire Roast/0/16/12/0/1000', 'Campfire Stew/5/12/9/4/1200', 'Wild Stew/8/5/5/12/1200', 'Fruit Salad/8/2/2/10/900', 'Meat Stock/5/8/9/3/700', 'Vegetable Stock/11/1/2/11/700', 'Camas Bulb Bake/12/7/5/4/400', 'Flatbread/17/8/3/0/500', 'Huckleberry Muffin/10/5/4/11/450', 'Baked Meat/0/13/17/0/600', 'Baked Roast/4/13/8/7/900', 'Huckleberry Pie/9/5/4/16/1300', 'Meat Pie/7/11/11/5/1300', 'Basic Salad/13/6/6/13/800', 'Simmered Meat/6/18/13/5/900', 'Vegetable Medley/9/5/8/20/900', 'Vegetable Soup/12/4/7/19/1200', 'Crispy Bacon/0/18/26/0/600', 'Stuffed Turkey/9/16/12/7/1500']
      main(list(read_foods(available)))





      share|improve this answer









      $endgroup$















        3












        3








        3





        $begingroup$


        1. Global variables are bad. Don't use them. I have to spend a long while looking at your code to tell what uses them and when. When your code becomes hundreds of lines long this is tedious and unmaintainable.



          If you need to use recursion and add to something not in the recursive function use a closure.



        2. You should load available into an object, rather than extract the information from it each and every time you use it.


        3. Using the above you can simplify all your totalNames, totalCarbs into one list.

        4. Rather than using AllSP and AllNames you can add a tuple to one list.

        5. You should put all your code into a main so that you reduce the amount of variables in the global scope. This goes hand in hand with (1).

        6. Rather than copying and pasting the same line multiple times you can create a function.

        All this gets the following. Which should be easier for you to increase the performance from:



        import itertools
        import sys
        import time
        import collections

        sys.setrecursionlimit(10000000)

        _Food = collections.namedtuple('Food', 'name carbs protein fat vitamins calories')

        class Food(_Food):
        @property
        def nutrients(self):
        return sum(self[1:5])


        def read_foods(foods):
        for food in foods:
        name, *other = food.split('/')
        yield Food(name, *[float(v) for v in other])


        def tot_avg(food, attr):
        return (
        sum(f.calories * getattr(f, attr) for f in food)
        / sum(f.calories for f in food)
        )


        def find_combs(available, MAXCALORIES):
        all_combinations = []
        def inner(total):
        for food in available:
        total_calories = [f.calories for f in total]
        if sum(total_calories) + food.calories <= MAXCALORIES:
        inner(total[:] + [food], MAXCALORIES)
        else:
        nutrients = [
        tot_avg(total, 'carbs'),
        tot_avg(total, 'protein'),
        tot_avg(total, 'fat'),
        tot_avg(total, 'vitamins')
        ]
        balance = sum(nutrients) / 2 / max(nutrients)
        sp = tot_avg(total, 'nutrients') * balance + 12
        all_combinations.append((sp, total))
        inner([])
        return all_combinations


        def main(available):
        for MAXCALORIES in range(100, 3000, 10):
        start = time.time()
        all_ = findcombs(available, MAXCALORIES)
        amount, foods = max(all_, key=lambda i: i[0])
        print(amount, ' ', [f.name for f in foods])
        print('Calories:', i, '>>> Time:', time.time()-start)


        if __name__ == '__main__':
        available = ['Fiddleheads/3/1/0/3/80', 'Fireweed Shoots/3/0/0/4/150', 'Prickly Pear Fruit/2/1/1/3/190', 'Huckleberries/2/0/0/6/80', 'Rice/7/1/0/0/90', 'Camas Bulb/1/2/5/0/120', 'Beans/1/4/3/0/120', 'Wheat/6/2/0/0/130', 'Crimini Mushrooms/3/3/1/1/200', 'Corn/5/2/0/1/230', 'Beet/3/1/1/3/230', 'Tomato/4/1/0/3/240', 'Raw Fish/0/3/7/0/200', 'Raw Meat/0/7/3/0/250', 'Tallow/0/0/8/0/200', 'Scrap Meat/0/5/5/0/50', 'Prepared Meat/0/4/6/0/600', 'Raw Roast/0/6/5/0/800', 'Raw Sausage/0/4/8/0/500', 'Raw Bacon/0/3/9/0/600', 'Prime Cut/0/9/4/0/600', 'Cereal Germ/5/0/7/3/20', 'Bean Paste/3/5/7/0/40', 'Flour/15/0/0/0/50', 'Sugar/15/0/0/0/50', 'Camas Paste/3/2/10/0/60', 'Cornmeal/9/3/3/0/60', 'Huckleberry Extract/0/0/0/15/60', 'Yeast/0/8/0/7/60', 'Oil/0/0/15/0/120', 'Infused Oil/0/0/12/3/120', 'Simple Syrup/12/0/3/0/400', 'Rice Sludge/10/1/0/2/450', 'Charred Beet/3/0/3/7/470', 'Camas Mash/1/2/9/1/500', 'Campfire Beans/1/9/3/0/500', 'Wilted Fiddleheads/4/1/0/8/500', 'Boiled Shoots/3/0/1/9/510', 'Charred Camas Bulb/2/3/7/1/510', 'Charred Tomato/8/1/0/4/510', 'Charred Corn/8/1/0/4/530', 'Charred Fish/0/9/4/0/550', 'Charred Meat/0/10/10/0/550', 'Wheat Porridge/10/4/0/10/510', 'Charred Sausage/0/11/15/0/500', 'Fried Tomatoes/12/3/9/2/560', 'Bannock/15/3/8/0/600', 'Fiddlehead Salad/6/6/0/14/970', 'Campfire Roast/0/16/12/0/1000', 'Campfire Stew/5/12/9/4/1200', 'Wild Stew/8/5/5/12/1200', 'Fruit Salad/8/2/2/10/900', 'Meat Stock/5/8/9/3/700', 'Vegetable Stock/11/1/2/11/700', 'Camas Bulb Bake/12/7/5/4/400', 'Flatbread/17/8/3/0/500', 'Huckleberry Muffin/10/5/4/11/450', 'Baked Meat/0/13/17/0/600', 'Baked Roast/4/13/8/7/900', 'Huckleberry Pie/9/5/4/16/1300', 'Meat Pie/7/11/11/5/1300', 'Basic Salad/13/6/6/13/800', 'Simmered Meat/6/18/13/5/900', 'Vegetable Medley/9/5/8/20/900', 'Vegetable Soup/12/4/7/19/1200', 'Crispy Bacon/0/18/26/0/600', 'Stuffed Turkey/9/16/12/7/1500']
        main(list(read_foods(available)))





        share|improve this answer









        $endgroup$




        1. Global variables are bad. Don't use them. I have to spend a long while looking at your code to tell what uses them and when. When your code becomes hundreds of lines long this is tedious and unmaintainable.



          If you need to use recursion and add to something not in the recursive function use a closure.



        2. You should load available into an object, rather than extract the information from it each and every time you use it.


        3. Using the above you can simplify all your totalNames, totalCarbs into one list.

        4. Rather than using AllSP and AllNames you can add a tuple to one list.

        5. You should put all your code into a main so that you reduce the amount of variables in the global scope. This goes hand in hand with (1).

        6. Rather than copying and pasting the same line multiple times you can create a function.

        All this gets the following. Which should be easier for you to increase the performance from:



        import itertools
        import sys
        import time
        import collections

        sys.setrecursionlimit(10000000)

        _Food = collections.namedtuple('Food', 'name carbs protein fat vitamins calories')

        class Food(_Food):
        @property
        def nutrients(self):
        return sum(self[1:5])


        def read_foods(foods):
        for food in foods:
        name, *other = food.split('/')
        yield Food(name, *[float(v) for v in other])


        def tot_avg(food, attr):
        return (
        sum(f.calories * getattr(f, attr) for f in food)
        / sum(f.calories for f in food)
        )


        def find_combs(available, MAXCALORIES):
        all_combinations = []
        def inner(total):
        for food in available:
        total_calories = [f.calories for f in total]
        if sum(total_calories) + food.calories <= MAXCALORIES:
        inner(total[:] + [food], MAXCALORIES)
        else:
        nutrients = [
        tot_avg(total, 'carbs'),
        tot_avg(total, 'protein'),
        tot_avg(total, 'fat'),
        tot_avg(total, 'vitamins')
        ]
        balance = sum(nutrients) / 2 / max(nutrients)
        sp = tot_avg(total, 'nutrients') * balance + 12
        all_combinations.append((sp, total))
        inner([])
        return all_combinations


        def main(available):
        for MAXCALORIES in range(100, 3000, 10):
        start = time.time()
        all_ = findcombs(available, MAXCALORIES)
        amount, foods = max(all_, key=lambda i: i[0])
        print(amount, ' ', [f.name for f in foods])
        print('Calories:', i, '>>> Time:', time.time()-start)


        if __name__ == '__main__':
        available = ['Fiddleheads/3/1/0/3/80', 'Fireweed Shoots/3/0/0/4/150', 'Prickly Pear Fruit/2/1/1/3/190', 'Huckleberries/2/0/0/6/80', 'Rice/7/1/0/0/90', 'Camas Bulb/1/2/5/0/120', 'Beans/1/4/3/0/120', 'Wheat/6/2/0/0/130', 'Crimini Mushrooms/3/3/1/1/200', 'Corn/5/2/0/1/230', 'Beet/3/1/1/3/230', 'Tomato/4/1/0/3/240', 'Raw Fish/0/3/7/0/200', 'Raw Meat/0/7/3/0/250', 'Tallow/0/0/8/0/200', 'Scrap Meat/0/5/5/0/50', 'Prepared Meat/0/4/6/0/600', 'Raw Roast/0/6/5/0/800', 'Raw Sausage/0/4/8/0/500', 'Raw Bacon/0/3/9/0/600', 'Prime Cut/0/9/4/0/600', 'Cereal Germ/5/0/7/3/20', 'Bean Paste/3/5/7/0/40', 'Flour/15/0/0/0/50', 'Sugar/15/0/0/0/50', 'Camas Paste/3/2/10/0/60', 'Cornmeal/9/3/3/0/60', 'Huckleberry Extract/0/0/0/15/60', 'Yeast/0/8/0/7/60', 'Oil/0/0/15/0/120', 'Infused Oil/0/0/12/3/120', 'Simple Syrup/12/0/3/0/400', 'Rice Sludge/10/1/0/2/450', 'Charred Beet/3/0/3/7/470', 'Camas Mash/1/2/9/1/500', 'Campfire Beans/1/9/3/0/500', 'Wilted Fiddleheads/4/1/0/8/500', 'Boiled Shoots/3/0/1/9/510', 'Charred Camas Bulb/2/3/7/1/510', 'Charred Tomato/8/1/0/4/510', 'Charred Corn/8/1/0/4/530', 'Charred Fish/0/9/4/0/550', 'Charred Meat/0/10/10/0/550', 'Wheat Porridge/10/4/0/10/510', 'Charred Sausage/0/11/15/0/500', 'Fried Tomatoes/12/3/9/2/560', 'Bannock/15/3/8/0/600', 'Fiddlehead Salad/6/6/0/14/970', 'Campfire Roast/0/16/12/0/1000', 'Campfire Stew/5/12/9/4/1200', 'Wild Stew/8/5/5/12/1200', 'Fruit Salad/8/2/2/10/900', 'Meat Stock/5/8/9/3/700', 'Vegetable Stock/11/1/2/11/700', 'Camas Bulb Bake/12/7/5/4/400', 'Flatbread/17/8/3/0/500', 'Huckleberry Muffin/10/5/4/11/450', 'Baked Meat/0/13/17/0/600', 'Baked Roast/4/13/8/7/900', 'Huckleberry Pie/9/5/4/16/1300', 'Meat Pie/7/11/11/5/1300', 'Basic Salad/13/6/6/13/800', 'Simmered Meat/6/18/13/5/900', 'Vegetable Medley/9/5/8/20/900', 'Vegetable Soup/12/4/7/19/1200', 'Crispy Bacon/0/18/26/0/600', 'Stuffed Turkey/9/16/12/7/1500']
        main(list(read_foods(available)))






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 20 mins ago









        PeilonrayzPeilonrayz

        25.9k338109




        25.9k338109























            2












            $begingroup$

            Data representation



            Your choice of data representation is curious. It's a middle ground between a fully-serialized text format and a fully-deserialized in-memory format (such as nested tuples or dictionaries). I'd offer that it's not as good as either of the above. If you're going for micro-optimization, you need to do "pre-deserialized" literal variable initialization that doesn't require parsing at all. The best option would probably be named tuples or even plain tuples, i.e.



            available = (
            ('Fiddleheads', 3, 1, 0, 3, 80),
            # ...
            )


            But this won't yield any noticeable benefit, and it's not as maintainable as the alternative: just write a CSV file.



            main isn't main



            You've written a main function that isn't actually top-level code. This is not advisable. Rename it to something else, and put your top-level code in an actual main function, called from global scope with a standard if __name__ == '__main__' check.



            list duplication



            This:



            totalNames[::]


            should simply be



            list(totalNames)


            snake_case



            Your names should follow the format total_names, rather than totalNames.



            Also, variables in global scope (i.e. AllSP) should be all-caps; and you shouldn't need to declare them global.



            I'm going to do some reading and see what you're doing in terms of algorithm and submit a second answer to suggest a saner one.






            share|improve this answer









            $endgroup$












            • $begingroup$
              Wow, thanks a lot! I'll edit my code following your advice now. Let me know if you find a way to optimise the algorithm!
              $endgroup$
              – Ruler Of The World
              3 hours ago










            • $begingroup$
              @RulerOfTheWorld Please do not edit the code in your question once reviewing started.
              $endgroup$
              – greybeard
              2 hours ago











            • $begingroup$
              @greybeard Of course, my apologies. I was not editing the code, but explaining the functions behind it in a section marked as an edit at the end of my post, so it wouldn't affect the previous code.
              $endgroup$
              – Ruler Of The World
              2 hours ago
















            2












            $begingroup$

            Data representation



            Your choice of data representation is curious. It's a middle ground between a fully-serialized text format and a fully-deserialized in-memory format (such as nested tuples or dictionaries). I'd offer that it's not as good as either of the above. If you're going for micro-optimization, you need to do "pre-deserialized" literal variable initialization that doesn't require parsing at all. The best option would probably be named tuples or even plain tuples, i.e.



            available = (
            ('Fiddleheads', 3, 1, 0, 3, 80),
            # ...
            )


            But this won't yield any noticeable benefit, and it's not as maintainable as the alternative: just write a CSV file.



            main isn't main



            You've written a main function that isn't actually top-level code. This is not advisable. Rename it to something else, and put your top-level code in an actual main function, called from global scope with a standard if __name__ == '__main__' check.



            list duplication



            This:



            totalNames[::]


            should simply be



            list(totalNames)


            snake_case



            Your names should follow the format total_names, rather than totalNames.



            Also, variables in global scope (i.e. AllSP) should be all-caps; and you shouldn't need to declare them global.



            I'm going to do some reading and see what you're doing in terms of algorithm and submit a second answer to suggest a saner one.






            share|improve this answer









            $endgroup$












            • $begingroup$
              Wow, thanks a lot! I'll edit my code following your advice now. Let me know if you find a way to optimise the algorithm!
              $endgroup$
              – Ruler Of The World
              3 hours ago










            • $begingroup$
              @RulerOfTheWorld Please do not edit the code in your question once reviewing started.
              $endgroup$
              – greybeard
              2 hours ago











            • $begingroup$
              @greybeard Of course, my apologies. I was not editing the code, but explaining the functions behind it in a section marked as an edit at the end of my post, so it wouldn't affect the previous code.
              $endgroup$
              – Ruler Of The World
              2 hours ago














            2












            2








            2





            $begingroup$

            Data representation



            Your choice of data representation is curious. It's a middle ground between a fully-serialized text format and a fully-deserialized in-memory format (such as nested tuples or dictionaries). I'd offer that it's not as good as either of the above. If you're going for micro-optimization, you need to do "pre-deserialized" literal variable initialization that doesn't require parsing at all. The best option would probably be named tuples or even plain tuples, i.e.



            available = (
            ('Fiddleheads', 3, 1, 0, 3, 80),
            # ...
            )


            But this won't yield any noticeable benefit, and it's not as maintainable as the alternative: just write a CSV file.



            main isn't main



            You've written a main function that isn't actually top-level code. This is not advisable. Rename it to something else, and put your top-level code in an actual main function, called from global scope with a standard if __name__ == '__main__' check.



            list duplication



            This:



            totalNames[::]


            should simply be



            list(totalNames)


            snake_case



            Your names should follow the format total_names, rather than totalNames.



            Also, variables in global scope (i.e. AllSP) should be all-caps; and you shouldn't need to declare them global.



            I'm going to do some reading and see what you're doing in terms of algorithm and submit a second answer to suggest a saner one.






            share|improve this answer









            $endgroup$



            Data representation



            Your choice of data representation is curious. It's a middle ground between a fully-serialized text format and a fully-deserialized in-memory format (such as nested tuples or dictionaries). I'd offer that it's not as good as either of the above. If you're going for micro-optimization, you need to do "pre-deserialized" literal variable initialization that doesn't require parsing at all. The best option would probably be named tuples or even plain tuples, i.e.



            available = (
            ('Fiddleheads', 3, 1, 0, 3, 80),
            # ...
            )


            But this won't yield any noticeable benefit, and it's not as maintainable as the alternative: just write a CSV file.



            main isn't main



            You've written a main function that isn't actually top-level code. This is not advisable. Rename it to something else, and put your top-level code in an actual main function, called from global scope with a standard if __name__ == '__main__' check.



            list duplication



            This:



            totalNames[::]


            should simply be



            list(totalNames)


            snake_case



            Your names should follow the format total_names, rather than totalNames.



            Also, variables in global scope (i.e. AllSP) should be all-caps; and you shouldn't need to declare them global.



            I'm going to do some reading and see what you're doing in terms of algorithm and submit a second answer to suggest a saner one.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 3 hours ago









            ReinderienReinderien

            4,250822




            4,250822











            • $begingroup$
              Wow, thanks a lot! I'll edit my code following your advice now. Let me know if you find a way to optimise the algorithm!
              $endgroup$
              – Ruler Of The World
              3 hours ago










            • $begingroup$
              @RulerOfTheWorld Please do not edit the code in your question once reviewing started.
              $endgroup$
              – greybeard
              2 hours ago











            • $begingroup$
              @greybeard Of course, my apologies. I was not editing the code, but explaining the functions behind it in a section marked as an edit at the end of my post, so it wouldn't affect the previous code.
              $endgroup$
              – Ruler Of The World
              2 hours ago

















            • $begingroup$
              Wow, thanks a lot! I'll edit my code following your advice now. Let me know if you find a way to optimise the algorithm!
              $endgroup$
              – Ruler Of The World
              3 hours ago










            • $begingroup$
              @RulerOfTheWorld Please do not edit the code in your question once reviewing started.
              $endgroup$
              – greybeard
              2 hours ago











            • $begingroup$
              @greybeard Of course, my apologies. I was not editing the code, but explaining the functions behind it in a section marked as an edit at the end of my post, so it wouldn't affect the previous code.
              $endgroup$
              – Ruler Of The World
              2 hours ago
















            $begingroup$
            Wow, thanks a lot! I'll edit my code following your advice now. Let me know if you find a way to optimise the algorithm!
            $endgroup$
            – Ruler Of The World
            3 hours ago




            $begingroup$
            Wow, thanks a lot! I'll edit my code following your advice now. Let me know if you find a way to optimise the algorithm!
            $endgroup$
            – Ruler Of The World
            3 hours ago












            $begingroup$
            @RulerOfTheWorld Please do not edit the code in your question once reviewing started.
            $endgroup$
            – greybeard
            2 hours ago





            $begingroup$
            @RulerOfTheWorld Please do not edit the code in your question once reviewing started.
            $endgroup$
            – greybeard
            2 hours ago













            $begingroup$
            @greybeard Of course, my apologies. I was not editing the code, but explaining the functions behind it in a section marked as an edit at the end of my post, so it wouldn't affect the previous code.
            $endgroup$
            – Ruler Of The World
            2 hours ago





            $begingroup$
            @greybeard Of course, my apologies. I was not editing the code, but explaining the functions behind it in a section marked as an edit at the end of my post, so it wouldn't affect the previous code.
            $endgroup$
            – Ruler Of The World
            2 hours ago











            Ruler Of The World is a new contributor. Be nice, and check out our Code of Conduct.









            draft saved

            draft discarded


















            Ruler Of The World is a new contributor. Be nice, and check out our Code of Conduct.












            Ruler Of The World is a new contributor. Be nice, and check out our Code of Conduct.











            Ruler Of The World is a new contributor. Be nice, and check out our Code of Conduct.














            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f215626%2foptimising-a-list-searching-algorithm%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Jet Time Laivasto | Lähteet | Aiheesta muualla | NavigointivalikkoJet Time - The CompanyThe CompanyManagementJet Time aloittaa lauantaina Suomi-rekisterissä olevalla Boeing 737 -koneellaJettime Finland Fleet Details and HistoryJettime Fleet Details and HistoryRegional Jet OÜ takes over ATR production for SASJet Time Returns To Its Core BusinessYhtiön kotisivutlaajentamalla

            Olympian arkeologinen museo Sisällysluettelo Historia ja rakennus | Kokoelmat | Lähteet | Aiheesta muualla | Navigointivalikko37°38′36″N, 21°37′46″EInfobox OKArchaeological Museum of Olympia: HistoryArchaeological Museum of Olympia: DescriptionΜουσείο Ιστορίας των Ολυμπιακών Αγώνων της Αρχαιότητας: ΙστορικόArchaeological Museum of Olympia

            Äpy Sisällysluettelo Äpyt kautta historian | Esimerkkejä Äpy-huumorista | Katso myös | Kirjallisuutta | Aiheesta muualla | Navigointivalikkowww.äpy.fi