From 68615a9ad2c942254135cffb00cf25a84a3b1356 Mon Sep 17 00:00:00 2001 From: Prefetch Date: Sat, 31 Dec 2022 22:21:39 +0100 Subject: Initial commit --- 15/input.txt | 4 ++++ 15/main.py | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 15/test.py | 23 ++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 15/input.txt create mode 100755 15/main.py create mode 100755 15/test.py (limited to '15') diff --git a/15/input.txt b/15/input.txt new file mode 100644 index 0000000..d1af06e --- /dev/null +++ b/15/input.txt @@ -0,0 +1,4 @@ +Sugar: capacity 3, durability 0, flavor 0, texture -3, calories 2 +Sprinkles: capacity -3, durability 3, flavor 0, texture 0, calories 9 +Candy: capacity -1, durability 0, flavor 4, texture 0, calories 1 +Chocolate: capacity 0, durability 0, flavor -2, texture 2, calories 8 diff --git a/15/main.py b/15/main.py new file mode 100755 index 0000000..cb2077b --- /dev/null +++ b/15/main.py @@ -0,0 +1,78 @@ +#!/usr/bin/python + + + +def parse_input(lines): + ingredients = [] + + for l in lines: + words = l.split() + + # Rather than label the properties by name, we number them 0-4 + props = [] + for n in range(5): + props.append(int(words[2 + 2 * n].rstrip(","))) + + name = words[0].rstrip(":") + ingredients.append(props) + + return ingredients + + + +def all_recipes(ingredients): + recipes = {} + + for i1 in range(101): + for i2 in range(101 - i1): + for i3 in range(101 - i1 - i2): + i4 = 100 - i1 - i2 - i3 + amounts = [i1, i2, i3, i4] # amount of each ingredient + + props = [0, 0, 0, 0] # score for each property + for p in range(len(props)): + # Accumulate properties of ingredients + for i in range(len(amounts)): + prop = amounts[i] * ingredients[i][p] + props[p] += prop + # Clamp negative totals to zero + if props[p] < 0: + props[p] = 0 + + # `recipes' is a dictionary: key is recipe, value is total score + recipes[tuple(amounts)] = props[0] * props[1] * props[2] * props[3] + + return recipes + + + +def solve_partn(partn, lines): + ingredients = parse_input(lines) + recipes = all_recipes(ingredients) + + if partn == 2: + suitable = {} + for amounts, score in recipes.items(): + calories = 0 + for i in range(len(amounts)): + calories += amounts[i] * ingredients[i][4] + if calories == 500: + suitable[amounts] = score + recipes = suitable + + return max(recipes.values()) + + + +def main(): + # Read ingredient information from input text file + with open("input.txt", "r") as f: + lines = f.read().splitlines() + + print("Part 1 solution:", solve_partn(1, lines)) # 222870 for me + print("Part 2 solution:", solve_partn(2, lines)) # 117936 for me + + + +if __name__ == "__main__": + main() diff --git a/15/test.py b/15/test.py new file mode 100755 index 0000000..fb71ad8 --- /dev/null +++ b/15/test.py @@ -0,0 +1,23 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class Examples(unittest.TestCase): + def test_example1(self): + lines = [ + "Butterscotch: capacity -1, durability -2, flavor 6, texture 3, calories 8", + "Cinnamon: capacity 2, durability 3, flavor -2, texture -1, calories 3", + "Dummy: capacity 0, durability 0, flavor 0, texture 0, calories 0", + "Dummy: capacity 0, durability 0, flavor 0, texture 0, calories 0" + ] + self.assertEqual(main.solve_partn(1, lines), 62842880) + self.assertEqual(main.solve_partn(2, lines), 57600000) + + + +if __name__ == "__main__": + unittest.main() -- cgit v1.2.3