2015-12-15 - Science for Hungry People
(original .ipynb)
Puzzle input is a list of ingredients and some properties about those. Part one involves finding the combination of these ingredients that maximises the product of all their properties (except calories). Part two involves finding the maximum scoring cookie that has exactly 500 calories.
from functools import reduce from collections import defaultdict puzzle_input_str = open("./puzzle_input/day15.txt").read() #- TODO: move to 'advent' library -------------------- def quantity_combinations(components, limit): for n in range(limit): if len(components[1:]) > 0: for res in quantity_combinations(components[1:], limit-n): yield [(components[0], n)] + res else: yield [(components[0], limit)] def prod(lst): return reduce(lambda x, y: x * y, lst) #------------------------------------------------------ def cookie_score(quantities, properties): subtotals = defaultdict(lambda:0) for ingredient, quantity in quantities: for prop in properties[ingredient]: subtotals[prop] += quantity * properties[ingredient][prop] score = prod(list( 0 if subtotals[prop] < 0 else subtotals[prop] for prop in subtotals if prop != "calories" )) calories = sum(subtotals[prop] for prop in subtotals if prop == "calories") return (score, calories) def parse_property(prop_str): prop, score = prop_str.split(" ") return prop, int(score) def parse_ingredient_properties(line): name, properties_str = line.split(":") properties = { p: score for p, score in [parse_property(prop) for prop in properties_str.lstrip(" ").split(", ")] } return name, properties def parse_input(input_str): return {name: properties for name, properties in [parse_ingredient_properties(line) for line in input_str.split("\n")]} def part_one(input_str): properties = parse_input(input_str) cookies = (cookie_score(cookie, properties) for cookie in quantity_combinations(list(properties.keys()), 100)) return max(score for score, calories in cookies) test_input_str = """Butterscotch: capacity -1, durability -2, flavor 6, texture 3, calories 8 Cinnamon: capacity 2, durability 3, flavor -2, texture -1, calories 3""" assert 62842880 == part_one(test_input_str) print("part one:", part_one(puzzle_input_str))
part one: 18965440
def part_two(input_str): properties = parse_input(input_str) cookies = (cookie_score(cookie, properties) for cookie in quantity_combinations(list(properties.keys()), 100)) return max(score for score, calories in cookies if calories == 500) assert 57600000 == part_two(test_input_str) print("part two:", part_two(puzzle_input_str))
part two: 15862900