diff --git a/src/Years/Y2015/Day9.md b/src/Years/Y2015/Day9.md index acb702c..cf83b37 100644 --- a/src/Years/Y2015/Day9.md +++ b/src/Years/Y2015/Day9.md @@ -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 ```