From 70a69ba86d10f98d13930b2764f1f0858cf0a056 Mon Sep 17 00:00:00 2001 From: aaron Date: Tue, 5 Dec 2023 16:23:06 +0100 Subject: [PATCH] add solution to day5 --- 5/fertilizer.py | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 5/fertilizer.py diff --git a/5/fertilizer.py b/5/fertilizer.py new file mode 100644 index 0000000..f2a637e --- /dev/null +++ b/5/fertilizer.py @@ -0,0 +1,72 @@ +from aocd.models import Puzzle +from aocd import submit +from functools import reduce +from operator import itemgetter + +import re + + +def parse_almanac(data): + NUMBER_RE = re.compile(r"\d+") + stanzas = data.split("\n\n") + return [int(m.group(0)) for m in NUMBER_RE.finditer(stanzas[0])], [ + sorted( + ( + (nums[1], nums[1] + nums[2], nums[0] - nums[1]) + for line in stanza.splitlines() + if len(nums := [int(m.group(0)) for m in NUMBER_RE.finditer(line)]) == 3 + ), + key=itemgetter(0), + ) + for stanza in stanzas[1:] + ] + + +def remap_almanac(ranges, mappings): + for start, end in ranges: + for start2, end2, offset in mappings: + if start2 >= end or start >= end2: + continue + if start < start2: + yield start, start2 + start = start2 + end2 = min(end, end2) + yield start + offset, end2 + offset + start = end2 + if start < end: + yield start, end + + +def part_a(data): + seeds, mappings = parse_almanac(data) + return min( + map(itemgetter(0), reduce(remap_almanac, mappings, ((x, x + 1) for x in seeds))) + ) + + +def part_b(data): + seeds, mappings = parse_almanac(data) + return min( + map( + itemgetter(0), + reduce( + remap_almanac, + mappings, + ((x, x + y) for x, y in zip(*[iter(seeds)] * 2)), + ), + ) + ) + + +if __name__ == "__main__": + # get puzzle and parse data + puzzle = Puzzle(year=2023, day=5) + + answer_a = part_a(puzzle.input_data) + print(f"{answer_a}") + submit(answer_a, part="a", day=5, year=2023) + + # part b: + answer_b = part_b(puzzle.input_data) + print(f"{answer_b}") + submit(answer_b, part="b", day=5, year=2023)