From c2da074b7c50264817cc4a8647b348dd6a7780d4 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Wed, 27 May 2026 22:54:26 +0200 Subject: [PATCH] 2O15 day 3, 4, and 6 part 1 --- adventofcode/2015/day3/day3.py | 52 +++++++++++++++++++++++++++++++ adventofcode/2015/day4/day4.py | 56 ++++++++++++++++++++++++++++++++++ adventofcode/2015/day6/day6.py | 36 ++++++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 adventofcode/2015/day3/day3.py create mode 100644 adventofcode/2015/day4/day4.py create mode 100644 adventofcode/2015/day6/day6.py diff --git a/adventofcode/2015/day3/day3.py b/adventofcode/2015/day3/day3.py new file mode 100644 index 0000000..e8d4514 --- /dev/null +++ b/adventofcode/2015/day3/day3.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +import fileinput +from itertools import zip_longest + + +def grouper(n, iterable): + "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" + args = [iter(iterable)] * n + return zip_longest(*args) + + +def move(c, x, y): + if c == "^": + y += 1 + elif c == ">": + x += 1 + elif c == "v": + y -= 1 + elif c == "<": + x -= 1 + return x, y + + +def part1(inp): + x, y = 0, 0 + visited = {(x, y)} + for c in inp: + x, y = move(c, x, y) + visited.add((x, y)) + print("Part 1: ", len(visited)) + + +def part2(inp): + x1, y1 = 0, 0 + x2, y2 = 0, 0 + visited = {(x1, y1)} + for move1, move2 in grouper(2, inp): + x1, y1 = move(move1, x1, y1) + x2, y2 = move(move2, x2, y2) + visited.add((x1, y1)) + visited.add((x2, y2)) + print("Part 2: ", len(visited)) + + +def main(inp): + part1(inp) + part2(inp) + + +if __name__ == "__main__": + inp = next(x.rstrip() for x in fileinput.input()) + main(inp) diff --git a/adventofcode/2015/day4/day4.py b/adventofcode/2015/day4/day4.py new file mode 100644 index 0000000..f15a426 --- /dev/null +++ b/adventofcode/2015/day4/day4.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +import sys +from hashlib import md5 +from multiprocessing import Process, Value + + +def solve(seed): + needle = "0" * 5 + for i in range(900_000): + hash = md5(seed + str(i).encode()).hexdigest() + if hash.startswith(needle): + # print(hash) + return i + assert False, "No solution found" + + +def worker(seed, start, step, stop_token, result): + i = start + while not stop_token.value: + d = md5(seed + str(i).encode()).digest() + if d[0] == 0 and d[1] == 0 and d[2] == 0: + stop_token.value = 1 + result.value = i # Store the result + return + i += step + + +def solve_parallel(seed): + stop_token = Value("b", 0, lock=False) + result = Value("i", -1) # Default: -1 (no result yet) + workers = [] + num_workers = 8 + for w in range(num_workers): + p = Process(target=worker, args=(seed, w, num_workers, stop_token, result)) + p.start() + workers.append(p) + + for p in workers: + p.join() + + # Print the result + if result.value != -1: + return result.value + else: + assert False, "No solution found" + + +def main(inp): + print("Part 1: ", solve(inp)) + print("Part 2: ", solve_parallel(inp)) + + +if __name__ == "__main__": + filename = sys.argv[1] if len(sys.argv) > 1 else "file not found" + with open(filename, "rb") as f: + main(f.readline().rstrip()) diff --git a/adventofcode/2015/day6/day6.py b/adventofcode/2015/day6/day6.py new file mode 100644 index 0000000..8aef340 --- /dev/null +++ b/adventofcode/2015/day6/day6.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +import fileinput +import re + + +def part1(inp): + """ + Part 1: simple brute force solution. Use a 1D array to represent the grid. + Use sice operations whenever possible because they are faster than iterating. + """ + grid = [False] * 1000 * 1000 + for line in inp: + x1, y1, x2, y2 = map(int, re.findall(r"(\d+)", line)) + x1, x2 = min(x1, x2), max(x1, x2) + y1, y2 = min(y1, y2), max(y1, y2) + for y in range(y1, y2 + 1): + start = y * 1000 + x1 + end = y * 1000 + x2 + 1 + # assigning to the slice is faster than iterating + if line.startswith("turn on"): + grid[start:end] = [True] * (end - start) + elif line.startswith("turn off"): + grid[start:end] = [False] * (end - start) + elif line.startswith("toggle"): + for i in range(start, end): + grid[i] = not grid[i] + return sum(grid) + + +def main(inp): + print("Part 1: ", part1(inp)) + + +if __name__ == "__main__": + lines = [x.rstrip() for x in fileinput.input()] + main(lines)