-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathDay24.hs
43 lines (36 loc) · 1.4 KB
/
Day24.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
module AOC2017.Day24 (day24a, day24b) where
import AOC2017.Types (Challenge)
import Control.Applicative (Alternative(..))
import Control.Monad.Trans.State (StateT(..), evalStateT)
import Data.Bifunctor (first)
import Data.List.Split (splitOn)
import Data.Ord (Down(..))
import Data.Tuple (swap)
type Comp = (Int, Int)
-- | All possible ways of selecting a single item from a list
select :: [a] -> [(a,[a])]
select = go []
where
go _ [] = []
go xs (y:ys) = (y,xs++ys) : go (y:xs) ys
bridge :: Int -> StateT [Comp] [] Int
bridge frm = do
(x,y) <- StateT select
next <- if | x == frm -> return y
| y == frm -> return x
| otherwise -> empty
rest <- return 0 -- account for a bridge that ends here
<|> bridge next -- account for a continued bridge
return $ x + y + rest
day24a :: Challenge
day24a = show . maximum
. evalStateT (bridge 0) . parse
day24b :: Challenge
day24b = show . snd . maximum
. map (first (Down . length) . swap) -- sort by lowest leftovers
. runStateT (bridge 0) . parse -- runState gives leftover components
parse :: String -> [Comp]
parse = map parseLine . lines
where
parseLine (splitOn "/"->(x:y:_)) = (read x, read y)
parseLine _ = error "No parse"