This repository has been archived by the owner on Nov 17, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Day13.hs
56 lines (51 loc) · 1.84 KB
/
Day13.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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
-- |
-- Module : AOC.Challenge.Day13
-- License : BSD3
--
-- Stability : experimental
-- Portability : non-portable
--
-- Day 13. See "AOC.Solver" for the types used in this module!
module AOC.Challenge.Day13 (
day13a
, day13b
) where
import AOC.Common (CharParser, parseMaybeLenient)
import AOC.Solver ((:~>)(..))
import Control.Applicative ((<|>))
import Data.Foldable (minimumBy)
import Data.List (foldl')
import Data.Maybe (mapMaybe, catMaybes)
import Data.Ord (comparing)
import qualified Text.Megaparsec as P
import qualified Text.Megaparsec.Char as P
import qualified Text.Megaparsec.Char.Lexer as PL
parseTrains :: Num a => CharParser [Maybe a]
parseTrains = (Nothing <$ P.char 'x' <|> Just <$> PL.decimal)
`P.sepBy` P.char ','
day13a :: (Int, [Int]) :~> (Int, Int)
day13a = MkSol
{ sParse = parseMaybeLenient $
(,) <$> (PL.decimal <* P.newline)
<*> (catMaybes <$> parseTrains)
, sShow = \(x,y) -> show $ x * y
, sSolve = \(t0, xs) -> Just $ minimumBy (comparing snd)
[ (x, waitTime)
| x <- xs
, let waitTime = x - (t0 `mod` x)
]
}
day13b :: [(Int, Int)] :~> Int
day13b = MkSol
{ sParse = parseMaybeLenient $ do
_ <- P.manyTill P.anySingle P.newline
mapMaybe sequenceA . zip [0,1..] <$> parseTrains
, sShow = show
, sSolve = Just . fst . foldl' go (0, 1)
}
where
go (!base, !step) (offset, i) = (base', step * i)
where
base' = until (\n -> (n + offset) `mod` i == 0)
(+ step)
base