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
`Choose` based effectful breath first search to identify all the possible paths
@ -210,11 +210,9 @@ lengths.
```idris
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
lens <- traverse pathLen paths
let pairs = zip paths lens
shortest pairs Nothing
shortest paths Nothing
where
shortest : List (a, Integer) -> (acc : Maybe (a, Integer))
-> Eff fs (a, Integer)
@ -228,6 +226,27 @@ shortestPath paths = do
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 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.
```idris
part1 : Eff (PartEff String) (Integer, ())
part1 :
Eff (PartEff String) (Integer, (DistanceMap, List (List Location, Integer)))
part1 = do
locations <- map lines (askAt "input") >>= traverse parseLocationPair
info "Locations: \{show locations}"
@ -246,13 +266,29 @@ part1 = do
paths <- map Prelude.toList allPaths
trace "Paths: \{show 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}"
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
public export
day9 : Day
day9 = First 9 part1
day9 = Both 9 part1 part2
-->