Advent of Code solutions
at main 26 lines 840 B view raw
1import Control.Arrow 2import Data.Either 3import Data.List 4import Data.Set qualified as Set 5 6score = sum . zipWith (*) [1..] . reverse 7 8play a b = play_ Set.empty a b 9 where 10 play_ _ a [] = Left $ score a 11 play_ _ [] b = Right $ score b 12 play_ cache a b | Set.member (a, b) cache = Left $ score a 13 play_ cache aa@(a:as) bb@(b:bs) 14 | a <= length as && b <= length bs = either (const awins) (const bwins) $ play (take a as) (take b bs) 15 | a > b = awins 16 | b > a = bwins 17 where 18 cache' = Set.insert (aa, bb) cache 19 awins = play_ cache' (as ++ [a, b]) bs 20 bwins = play_ cache' as (bs ++ [b, a]) 21 22answer contents = either id id $ play p1 p2 23 where 24 (p1, p2) :: ([Int], [Int]) = (fmap read . tail *** fmap read . drop 2) $ break null $ lines contents 25 26main = getContents >>= print . answer