From 0bee46a0adf811fdd3b25b72fe353e3d5fcebbb3 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Wed, 13 May 2026 18:09:00 +0200 Subject: [PATCH] solve some days --- .gitignore | 3 +- adventofcode/2015/day12/day12.py | 44 ++++++++++++++++++ adventofcode/2015/day2/day2.py | 28 ++++++++++++ adventofcode/2015/day5/day5.py | 78 ++++++++++++++++++++++++++++++++ 4 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 adventofcode/2015/day12/day12.py create mode 100644 adventofcode/2015/day2/day2.py create mode 100644 adventofcode/2015/day5/day5.py diff --git a/.gitignore b/.gitignore index 4b6f247..74d63ab 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,8 @@ coverage.xml .hypothesis/ .pytest_cache/ +.ruff_cache/ + # Translations *.mo *.pot @@ -131,4 +133,3 @@ dmypy.json # Pyre type checker .pyre/ - diff --git a/adventofcode/2015/day12/day12.py b/adventofcode/2015/day12/day12.py new file mode 100644 index 0000000..af1e7aa --- /dev/null +++ b/adventofcode/2015/day12/day12.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + +import json +import re +from collections import deque + + +def main(inp): + total = sum(map(int, re.findall(r"(-?\d+)", inp))) + print("Part 1: ", total) + root = json.loads(inp) + print("Part 2: ", bfs(root)) + + +def bfs(json_data): + """ + BFS on the json data and sum all the numbers. If a node contains the value + "red", we skip it and all its children + """ + queue = deque([(json_data, "")]) # (node, path) + visited = set() + total = 0 + while queue: + node, path = queue.popleft() + if path not in visited: + visited.add(path) + if isinstance(node, int): + total += node + elif isinstance(node, dict): + has_red = "red" in node.values() + if not has_red: + for key, child in node.items(): + queue.append((child, f"{path}.{key}")) + elif isinstance(node, list): + for idx, child in enumerate(node): + queue.append((child, f"{path}[{idx}]")) + return total + + +if __name__ == "__main__": + import fileinput + + line = next(fileinput.input()).rstrip() + main(line) diff --git a/adventofcode/2015/day2/day2.py b/adventofcode/2015/day2/day2.py new file mode 100644 index 0000000..4e0f536 --- /dev/null +++ b/adventofcode/2015/day2/day2.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +from functools import reduce +from operator import mul + + +def part1(inp): + total = 0 + for line in inp: + l, w, h = map(int, line.split("x")) + faces = [l * w, w * h, h * l] + total += sum(2 * x for x in faces) + min(faces) + print("Part 1: ", total) + + +def part2(inp): + total = 0 + for line in inp: + line = list(map(int, line.split("x"))) + total += sum(sorted(line)[:2]) * 2 + reduce(mul, line, 1) + print("Part 2:", total) + + +if __name__ == "__main__": + import fileinput + + lines = [x.rstrip() for x in fileinput.input()] + part1(lines) + part2(lines) diff --git a/adventofcode/2015/day5/day5.py b/adventofcode/2015/day5/day5.py new file mode 100644 index 0000000..8493b19 --- /dev/null +++ b/adventofcode/2015/day5/day5.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +from itertools import islice + +VOWELS = "aeiou" +BAD = ["ab", "cd", "pq", "xy"] + + +def window(seq, n=3): + "Returns a sliding window (of width n) over data from the iterable" + " s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ... " + it = iter(seq) + result = tuple(islice(it, n)) + if len(result) == n: + yield result + for elem in it: + result = result[1:] + (elem,) + yield result + + +def part1(inp): + total = 0 + for line in inp: + """ + - It contains at least three vowels (aeiou only), like aei, xazegov, or + aeiouaeiouaeiou. + - It contains at least one letter that appears twice in a row, like xx, + abcdde (dd), or aabbccdd (aa, bb, cc, or dd). + - It does not contain the strings ab, cd, pq, or xy, even if they are + part of one of the other requirements. + """ + if any(x in line for x in BAD) or sum(1 for x in line if x in VOWELS) < 3: + continue + total += any(a == b for a, b in zip(line, line[1:])) + print("Part 1: ", total) + + +def part2(inp): + """ + - It contains a pair of any two letters that appears at least twice in the + string without overlapping, like xyxy (xy) or aabcdefgaa (aa), but not like + aaa (aa, but it overlaps). + - It contains at least one letter which repeats with exactly one letter + between them, like xyx, abcdefeghi (efe), or even aaa. + """ + total = 0 + for line in inp: + has_repeat = False + for triplet in window(line, n=3): + if triplet[0] == triplet[2]: + has_repeat = True + break + + seen_pairs = set() + has_pair = False + prev_pair = None + for pair in window(line, n=2): + if pair in seen_pairs: + has_pair = True + else: + # Add the previous pair to avoid overlapping + if prev_pair is not None: + seen_pairs.add(prev_pair) + prev_pair = pair + if has_pair and has_repeat: + break # Early exit when both conditions are met + + if has_pair and has_repeat: + total += 1 + + print("Part 2: ", total) + + +if __name__ == "__main__": + import fileinput + + lines = [x.rstrip() for x in fileinput.input()] + part1(lines) + part2(lines)