Commit 330458a7 authored by Germain Clavier's avatar Germain Clavier 😺
Browse files

Added day5 solution

parent f5992c2d
Loading
Loading
Loading
Loading

2023/day5/code.py

0 → 100644
+138 −0
Original line number Diff line number Diff line
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Solution for day 5 2023
"""

import time
import argparse as ap
import copy
import sys
from functools import reduce


def convert_range(inputs, mappings):
    for start, length in inputs:
        while length > 0:
            for m in mappings.split("\n")[1:]:
                dst, src, len = map(int, m.strip().split())
                delta = start - src
                if delta in range(len):
                    len = min(len - delta, length)
                    yield (dst + delta, len)
                    start += len
                    length -= len
                    break
            else:
                yield (start, length)
                break


def solve2(file=None, verbose=False, solution=0):
    """
    This snippet was cleverly set up by 4HBq. Link here:
    https://www.reddit.com/r/adventofcode/comments/18b4b0r/comment/kc2au1l/?utm_source=share&utm_medium=web2x&context=3
    Took me a while to get the reduce and generator part but I finally figured out why it worked as is.
    """
    try:
        seeds, *mappings = open(file).read().split("\n\n")
        seeds = list(map(int, seeds.split()[1:]))

        solution = [
            min(reduce(convert_range, mappings, s))[0]
            for s in [zip(seeds[0::2], seeds[1::2])]
        ][0]
    except FileNotFoundError:
        pass

    return solution


def convert(f, field1, field2, verbose=False):
    """
    Reads a map and computes the corresponding values to field1 to field2
    """
    while line := f.readline():
        if "map" in line:
            continue
        elif line.isspace():
            break
        (start2, start1, ran) = map(int, line.split())
        delta2 = start2 - start1
        for j, f1 in enumerate(field1):
            if f1 > start1 and f1 < start1 + ran:
                field2[j] += delta2
    if verbose:
        print(field1, field2)

    return


def solve1(file=None, verbose=False, solution=0):
    try:
        with open(file, "r") as f:
            seeds = list(map(int, f.readline().split()[1:]))
            f.readline()
            soils = copy.deepcopy(seeds)
            print("Converting soils...")
            convert(f, seeds, soils, verbose)
            ferti = copy.deepcopy(soils)
            print("Converting ferti...")
            convert(f, soils, ferti, verbose)
            water = copy.deepcopy(ferti)
            print("Converting water...")
            convert(f, ferti, water, verbose)
            light = copy.deepcopy(water)
            print("Converting light...")
            convert(f, water, light, verbose)
            tempe = copy.deepcopy(light)
            print("Converting tempe...")
            convert(f, light, tempe, verbose)
            humid = copy.deepcopy(tempe)
            print("Converting humid...")
            convert(f, tempe, humid, verbose)
            locat = copy.deepcopy(humid)
            print("Converting locat...")
            convert(f, humid, locat, verbose)
            solution = min(locat)
        if verbose:
            print("Seeds: {:}".format(seeds))
            print("Soils: {:}".format(soils))
            print("Ferti: {:}".format(ferti))
            print("Water: {:}".format(water))
            print("Light: {:}".format(light))
            print("Tempe: {:}".format(tempe))
            print("Humid: {:}".format(humid))
            print("Locat: {:}".format(locat))
    except FileNotFoundError:
        pass
    return solution


def main():
    parser = ap.ArgumentParser()
    parser.add_argument("-i", dest="input", action="store_true")
    parser.add_argument("-v", dest="verbose", action="store_true")
    args = parser.parse_args()
    infile = "input" if args.input else "test"
    verbose = args.verbose

    t0 = time.time()
    sol1 = solve1(infile, verbose)
    dt = time.time() - t0
    print(f"Solution 1: {sol1}, Time: {dt}")

    t0 = time.time()
    sol2 = solve2(infile, verbose)
    dt = time.time() - t0
    print(f"Solution 2: {sol2}, Time: {dt}")

    return


if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        raise SystemExit("User interruption.")

2023/day5/test

0 → 100644
+34 −0
Original line number Diff line number Diff line
seeds: 79 14 55 13

seed-to-soil map:
50 98 2
52 50 48

soil-to-fertilizer map:
0 15 37
37 52 2
39 0 15

fertilizer-to-water map:
49 53 8
0 11 42
42 0 7
57 7 4

water-to-light map:
88 18 7
18 25 70

light-to-temperature map:
45 77 23
81 45 19
68 64 13

temperature-to-humidity map:
0 69 1
1 0 69

humidity-to-location map:
60 56 37
56 93 4