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
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
You are viewing a single thread.
View all comments 2 points
Haskell
import Control.Arrow
import Control.Monad.Reader
import Data.Array.Unboxed
import Data.List
type Pos = (Int, Int)
type Board = UArray Pos Char
type Prob = Reader Board
parse :: String -> Board
parse s = listArray ((1, 1), (n, m)) $ concat l
where
l = lines s
n = length l
m = length $ head l
origins :: Prob [Pos]
origins =
ask >>= \board ->
return $ fmap fst . filter ((== '0') . snd) $ assocs board
moves :: Pos -> Prob [Pos]
moves pos =
ask >>= \board ->
let curr = board ! pos
in return . filter ((== succ curr) . (board !)) . filter (inRange (bounds board)) $ fmap (.+. pos) deltas
where
deltas = [(1, 0), (0, 1), (-1, 0), (0, -1)]
(ax, ay) .+. (bx, by) = (ax + bx, ay + by)
solve :: [Pos] -> Prob [Pos]
solve p = do
board <- ask
nxt <- concat <$> mapM moves p
let (nines, rest) = partition ((== '9') . (board !)) nxt
fmap (++ nines) $ if null rest then return [] else solve rest
scoreTrail = fmap (length . nub) . solve . pure
scoreTrail' = fmap length . solve . pure
part1 = sum . runReader (origins >>= mapM scoreTrail)
part2 = sum . runReader (origins >>= mapM scoreTrail')
main = getContents >>= print . (part1 &&& part2) . parse