interviews-in23/src/INSolver.hs

39 lines
1.4 KiB
Haskell

{-# OPTIONS_GHC -Wno-missing-signatures #-}
module INSolver where
import Control.Monad
import Control.Monad.State
import Data.List (tails,find)
import INAST
-- solve :: Int -> InsuranceNetworkAST -> [INASTInsurerId]
solve i = maybe [] (map unNASTInsurerId . reverse . fst)
. find ((== 100) . snd)
. map foldMe
. tails
. flip execState []
. mapM potentialInsId
where
foldMe :: [(INASTInsurerId,INASTPercent)] -> ([INASTInsurerId],Int)
foldMe = foldr (\ (i',INASTPercent p) (ixacc,pacc) -> (i':ixacc,p+pacc)) ([],0)
-- | Result is sensitive to order of execution.
-- One thing not speficied in the problem statement is whether expressions
-- only apply to previous lines, or if they can be looking forward
-- Here we're assuming the former case holds true.
potentialInsId :: INASTLine -> State [(INASTInsurerId,INASTPercent)] ()
potentialInsId (INASTLine iid pct exprs) = do
insidpctx <- get
when (allExprEval i insidpctx exprs) (modify ((iid,pct) :))
allExprEval :: Int -> [(INASTInsurerId,INASTPercent)] -> [INASTExpr] -> Bool
allExprEval i xs = all (exprEval i (map fst xs))
exprEval :: Int -> [INASTInsurerId] -> INASTExpr -> Bool
exprEval i _ (INASTExprLt (INASTLt n)) = i < n
exprEval i _ (INASTExprGt (INASTGt n)) = i > n
exprEval i _ (INASTExprEq (INASTEq n)) = i == n
exprEval _ insx (INASTExprInsurerId insid) = insid `elem` insx