From ac0b8697bb6d6291fc95cfa387d4c807d67b3ce7 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Fri, 5 Jun 2026 11:05:24 +0200 Subject: [PATCH] 2015 day 15 --- adventofcode/2015/day15/day15.py | 105 +++++++++++++++++++++++++++++++ adventofcode/helper.py | 7 ++- 2 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 adventofcode/2015/day15/day15.py diff --git a/adventofcode/2015/day15/day15.py b/adventofcode/2015/day15/day15.py new file mode 100644 index 0000000..dd708d7 --- /dev/null +++ b/adventofcode/2015/day15/day15.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +import fileinput +import re +from functools import reduce +from itertools import combinations +from operator import mul + + +def parse_ingredients(inp): + ingredients = [] + for line in inp: + ingredients.append(tuple(map(int, re.findall(r"(-?\d+)", line)))) + return ingredients + + +def generate_combinations(): + "Generate combinations of length 4 that sum to 100" + for x, y, z in combinations(range(1, 100), 3): + a = x + b = y - x + c = z - y + d = 100 - z + yield (a, b, c, d) + + +def example(ingredients): + # for example input, two ingredients such that + # a + b = 100 with a and b >= 0 + max_score = 0 + for a in range(0, 101): + b = 100 - a + # ignore last property (calories) + qty_a = [x * a for x in ingredients[0][:-1]] + qty_b = [x * b for x in ingredients[1][:-1]] + props = [x + y if x + y > 0 else 0 for x, y in zip(qty_a, qty_b)] + score = reduce(mul, props) + max_score = max(score, max_score) + return max_score + + +def example_part2(ingredients): + max_score = 0 + for a in range(0, 101): + b = 100 - a + qty_a = [x * a for x in ingredients[0]] + qty_b = [x * b for x in ingredients[1]] + # check calories == 500 + if qty_a[-1] + qty_b[-1] != 500: + continue + props = [x + y if x + y > 0 else 0 for x, y in zip(qty_a, qty_b)] + score = reduce(mul, props[:-1]) + max_score = max(score, max_score) + return max_score + + +def part1(ingredients): + max_score = 0 + for a, b, c, d in generate_combinations(): + qty_a = [x * a for x in ingredients[0][:-1]] + qty_b = [x * b for x in ingredients[1][:-1]] + qty_c = [x * c for x in ingredients[2][:-1]] + qty_d = [x * d for x in ingredients[3][:-1]] + props = [ + x + y + z + w if x + y + z + w > 0 else 0 + for x, y, z, w in zip(qty_a, qty_b, qty_c, qty_d) + ] + score = reduce(mul, props) + max_score = max(score, max_score) + return max_score + + +def part2(ingredients): + max_score = 0 + for a, b, c, d in generate_combinations(): + qty_a = [x * a for x in ingredients[0]] + qty_b = [x * b for x in ingredients[1]] + qty_c = [x * c for x in ingredients[2]] + qty_d = [x * d for x in ingredients[3]] + props = [ + x + y + z + w if x + y + z + w > 0 else 0 + for x, y, z, w in zip(qty_a, qty_b, qty_c, qty_d) + ] + # check calories == 500 + calories = sum(x[-1] for x in [qty_a, qty_b, qty_c, qty_d]) + if calories != 500: + continue + score = reduce(mul, props[:-1]) + max_score = max(score, max_score) + return max_score + + +def main(inp): + ingredients = parse_ingredients(inp) + if len(ingredients) == 2: # example + print("Part 1: ", example(ingredients)) + print("Part 2: ", example_part2(ingredients)) + else: + print("Part 1: ", part1(ingredients)) + print("Part 2: ", part2(ingredients)) + + +if __name__ == "__main__": + with fileinput.input() as f: + lines = [x.rstrip() for x in fileinput.input()] + main(lines) diff --git a/adventofcode/helper.py b/adventofcode/helper.py index 3ee0060..7f3dcec 100644 --- a/adventofcode/helper.py +++ b/adventofcode/helper.py @@ -14,12 +14,13 @@ import fileinput def main(inp): - for l in inp: - print(l) + for line in inp: + print(line) if __name__ == '__main__': - lines = [x.rstrip() for x in fileinput.input()] + with fileinput.input() as f: + lines = [x.rstrip() for x in fileinput.input()] main(lines) """