day05
This commit is contained in:
parent
209f0ff0cc
commit
4bd4d1b4a1
1 changed files with 70 additions and 0 deletions
70
2023/day05.nim
Normal file
70
2023/day05.nim
Normal file
|
@ -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.
|
Loading…
Add table
Reference in a new issue