-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathDay5.hs
36 lines (32 loc) · 1.28 KB
/
Day5.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{-|
Module: Day5
Description: <https://adventofcode.com/2022/day/5 Day 5: Supply Stacks>
-}
{-# LANGUAGE OverloadedStrings, ViewPatterns #-}
module Day5 (day5a, day5b) where
import Data.Char (isDigit)
import Data.List (foldl')
import Data.List.Split (splitWhen)
import qualified Data.Map as Map
import Data.Maybe (mapMaybe)
import Data.Text (Text)
import qualified Data.Text as T (append, lines, null, reverse, splitAt, stripStart, transpose, unpack, unsnoc, words)
import qualified Data.Text.Read as T (decimal)
day5 :: (Text -> Text) -> Text -> Text
day5 f input = head . T.transpose . Map.elems $ foldl' go stacks0 moves where
[top, bottom] = splitWhen T.null $ T.lines input
stack (T.unsnoc -> Just (s, x)) | isDigit x = Just (x, T.stripStart s)
stack _ = Nothing
stacks0 = Map.fromList . mapMaybe stack $ T.transpose top
move ["move", T.decimal -> Right (num, ""), "from", T.unpack -> [x], "to", T.unpack -> [y]]
| isDigit x, isDigit y
= Just (num, x, y)
move _ = Nothing
moves = mapMaybe (move . T.words) bottom
go stacks (num, x, y) =
let (a, b) = T.splitAt num $ stacks Map.! x
in Map.update (Just . T.append (f a)) y $ Map.insert x b stacks
day5a :: Text -> Text
day5a = day5 T.reverse
day5b :: Text -> Text
day5b = day5 id