module AOC.Challenge.Day07 (
day07a
, day07b
) where
import AOC.Common.Intcode (Memory, VM, IErr, untilHalt, stepForeverAndDie, parseMem, yieldAndDie, yieldAndPass)
import AOC.Solver ((:~>)(..))
import AOC.Util (eitherToMaybe)
import Control.Monad.Except (MonadError)
import Data.Conduino ((.|), runPipePure, runPipe, awaitSurely, feedbackPipe)
import Data.List (permutations)
import Data.Semigroup (Max(..))
import Data.Void (Void)
import qualified Data.Conduino.Combinators as C
setupChain :: MonadError IErr m => Memory -> [Int] -> VM m Void
setupChain m = foldr ((.|) . prime) (C.map id)
where
prime i = yieldAndPass i
.| stepForeverAndDie m
day07a :: Memory :~> Int
day07a = MkSol
{ sParse = parseMem
, sShow = show
, sSolve = \m -> fmap getMax . flip foldMap (permutations [0..4]) $ \xs ->
let res = runPipe $ yieldAndDie 0
.| setupChain m xs
.| awaitSurely
in Max <$> eitherToMaybe res
}
day07b :: Memory :~> Int
day07b = MkSol
{ sParse = parseMem
, sShow = show
, sSolve = \m -> fmap getMax . flip foldMap (permutations [5..9]) $ \xs ->
let res = runPipePure $ untilHalt ( yieldAndDie 0
.| feedbackPipe (setupChain m xs)
)
.| C.last
in Max <$> res
}