From 4bd4d1b4a17e938a84a5f0bc7810b402e1bb4ccd Mon Sep 17 00:00:00 2001 From: Rupus Reinefjord Date: Sun, 10 Dec 2023 22:32:02 +0100 Subject: [PATCH] day05 --- 2023/day05.nim | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 2023/day05.nim diff --git a/2023/day05.nim b/2023/day05.nim new file mode 100644 index 0000000..8a60be8 --- /dev/null +++ b/2023/day05.nim @@ -0,0 +1,70 @@ +import std/[sequtils, strutils, sugar, threadpool] + +type + CatMap = seq[tuple[srcStart, dstStart, range: int]] + +func get(catMap: CatMap, thing: int): int = + for m in catMap: + let + low = m.srcStart + high = m.srcStart + m.range - 1 + if low <= thing and thing <= high: + return m.dstStart + (thing - m.srcStart) + return thing + +func location(catMaps: seq[CatMap], thing: int): int = + result = thing + for catMap in catMaps: + result = catMap.get(result) + +func catMaps(lines: seq[string]): CatMap = + for line in lines[1..^1]: + let + sp = line.split(' ') + ints = sp.map(parseInt) + md = (srcStart: ints[1], dstStart: ints[0], range: ints[2]) + result.add(md) + +func parseSeeds(s: string): seq[int] = s.split(' ')[1..^1].map(parseInt) + +proc p1(input: string) = + let + parts = input.strip().split("\n\n") + seeds = parts[0].parseSeeds() + maps = parts[1..^1].mapIt(splitLines(it)).map(catMaps) + echo seeds.mapIt(location(maps, it)).min() + +func seedRanges(ranges: seq[int]): seq[(int, int)] = + for i in countup(0, ranges.high, 2): + let + start = ranges[i] + stop = start + ranges[i+1] - 1 + result.add (start, stop) + +func lowest(maps: seq[CatMap], start, stop: int): int = + result = high(int) + for seed in start..stop: + let loc = maps.location(seed) + if loc < result: + result = loc + +proc p2(input: string) = + let + parts = input.strip().split("\n\n") + ranges = parts[0].parseSeeds() + maps = parts[1..^1].mapIt(splitLines(it)).map(catMaps) + + let responses: seq[FlowVar[int]] = collect: + for (start, stop) in seedRanges(ranges): + spawn lowest(maps, start, stop) + sync() + + let locations = collect: + for r in responses: + ^r + echo min(locations) + +when isMainModule: + let input = stdin.readAll() + p1(input) + p2(input) # takes a minute or two.