summaryrefslogtreecommitdiff
path: root/15/main.py
blob: cb2077b7d57df8ce25128539b58c3605c1e622fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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()