Day 10: Hoof It

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

  • lwhjp@lemmy.sdf.org
    link
    fedilink
    arrow-up
    4
    ·
    16 days ago

    Haskell

    A nice easy one today: didn’t even have to hit this with the optimization hammer.

    import Data.Char
    import Data.List
    import Data.Map (Map)
    import Data.Map qualified as Map
    
    readInput :: String -> Map (Int, Int) Int
    readInput s =
      Map.fromList
        [ ((i, j), digitToInt c)
          | (i, l) <- zip [0 ..] (lines s),
            (j, c) <- zip [0 ..] l
        ]
    
    findTrails :: Map (Int, Int) Int -> [[[(Int, Int)]]]
    findTrails input =
      Map.elems . Map.map (filter ((== 10) . length)) $
        Map.restrictKeys accessible starts
      where
        starts = Map.keysSet . Map.filter (== 0) $ input
        accessible = Map.mapWithKey getAccessible input
        getAccessible (i, j) h
          | h == 9 = [[(i, j)]]
          | otherwise =
              [ (i, j) : path
                | (di, dj) <- [(-1, 0), (0, 1), (1, 0), (0, -1)],
                  let p = (i + di, j + dj),
                  input Map.!? p == Just (succ h),
                  path <- accessible Map.! p
              ]
    
    main = do
      trails <- findTrails . readInput <$> readFile "input10"
      mapM_
        (print . sum . (`map` trails))
        [length . nub . map last, length]