Year 2015 Day 9 Part 2

This commit is contained in:
Nathan McCarty 2025-01-19 18:46:24 -05:00
parent c46d3d911b
commit cf3a81fa62

View file

@ -1,4 +1,4 @@
# Year 2016 Day 9 # Year 2015 Day 9
This day provides our first example of a graph traversal problem. We'll use a This day provides our first example of a graph traversal problem. We'll use a
`Choose` based effectful breath first search to identify all the possible paths `Choose` based effectful breath first search to identify all the possible paths
@ -210,11 +210,9 @@ lengths.
```idris ```idris
shortestPath : Has (Reader DistanceMap) fs => Has (Except String) fs => shortestPath : Has (Reader DistanceMap) fs => Has (Except String) fs =>
(paths : List (List Location)) -> Eff fs (List Location, Integer) (paths : List (List Location, Integer)) -> Eff fs (List Location, Integer)
shortestPath paths = do shortestPath paths = do
lens <- traverse pathLen paths shortest paths Nothing
let pairs = zip paths lens
shortest pairs Nothing
where where
shortest : List (a, Integer) -> (acc : Maybe (a, Integer)) shortest : List (a, Integer) -> (acc : Maybe (a, Integer))
-> Eff fs (a, Integer) -> Eff fs (a, Integer)
@ -228,6 +226,27 @@ shortestPath paths = do
else shortest xs (Just y) else shortest xs (Just y)
``` ```
Calculate the longest path from a list of paths by recursively comparing
lengths.
```idris
longestPath : Has (Reader DistanceMap) fs => Has (Except String) fs =>
(paths : List (List Location, Integer)) -> Eff fs (List Location, Integer)
longestPath paths = do
longest paths Nothing
where
longest : List (a, Integer) -> (acc : Maybe (a, Integer))
-> Eff fs (a, Integer)
longest [] acc = note "No paths" acc
longest (x :: xs) acc =
case acc of
Nothing => longest xs (Just x)
Just y =>
if (snd x) > (snd y)
then longest xs (Just x)
else longest xs (Just y)
```
## Part Functions ## Part Functions
### Part 1 ### Part 1
@ -236,7 +255,8 @@ Parse our locations, turn them into a `DistanceMap`, load that into our reader,
generate our paths, then find the one with the shortest length. generate our paths, then find the one with the shortest length.
```idris ```idris
part1 : Eff (PartEff String) (Integer, ()) part1 :
Eff (PartEff String) (Integer, (DistanceMap, List (List Location, Integer)))
part1 = do part1 = do
locations <- map lines (askAt "input") >>= traverse parseLocationPair locations <- map lines (askAt "input") >>= traverse parseLocationPair
info "Locations: \{show locations}" info "Locations: \{show locations}"
@ -246,13 +266,29 @@ part1 = do
paths <- map Prelude.toList allPaths paths <- map Prelude.toList allPaths
trace "Paths: \{show paths}" trace "Paths: \{show paths}"
info "Found \{show $ length paths} paths" info "Found \{show $ length paths} paths"
(path, len) <- shortestPath paths distances <- traverse pathLen paths
let pairs = zip paths distances
(path, len) <- shortestPath pairs
info "Shortest Path: \{show path} \{show len}" info "Shortest Path: \{show path} \{show len}"
pure (len, ()) pure (len, (distance_map, pairs))
```
### Part 2
Feed the locations back into a longest path function
```idris
part2 : (DistanceMap, List (List Location, Integer))
-> Eff (PartEff String) Integer
part2 (distance_map, pairs) = do
runReader distance_map {fs = Reader DistanceMap :: PartEff String} $ do
(path, len) <- longestPath pairs
info "Longest Path: \{show path} \{show len}"
pure len
``` ```
<!-- idris <!-- idris
public export public export
day9 : Day day9 : Day
day9 = First 9 part1 day9 = Both 9 part1 part2
--> -->