X-Git-Url: https://git.njae.me.uk/?p=advent-of-code-19.git;a=blobdiff_plain;f=advent25%2Fsrc%2Fadvent25.hs;h=c9a74573d6cd867e108992c143243026fd9ed9db;hp=c3c0c1f17de6dab420291e2a11000bbee5cb2685;hb=HEAD;hpb=3678ceddbeee0dd08141a177709579ee494bc8da diff --git a/advent25/src/advent25.hs b/advent25/src/advent25.hs index c3c0c1f..c9a7457 100644 --- a/advent25/src/advent25.hs +++ b/advent25/src/advent25.hs @@ -6,6 +6,10 @@ import qualified Data.Text.IO as TIO import qualified Data.Text as T import Data.Char import Data.List +import Control.Monad.Reader + +type CachedMachine a = Reader (Machine, [String]) a + main :: IO () main = do @@ -31,7 +35,8 @@ runPreamble mem = encodeCommands :: [String] -> [Integer] -encodeCommands cmds = map (fromIntegral . ord) $ concat $ map (++ "\n") cmds +-- encodeCommands cmds = map (fromIntegral . ord) $ concat $ map (++ "\n") cmds +encodeCommands = map (fromIntegral . ord) . concat . map (++ "\n") decodeOutput :: [Integer] -> String decodeOutput = map (chr . fromIntegral) @@ -46,23 +51,33 @@ powerList :: [a] -> [[a]] powerList [] = [[]] powerList (x:xs) = powerList xs ++ map (x:) (powerList xs) - passSecurity :: Machine -> [String] -> [String] -> String -passSecurity machine instructions items = - "You keep: " ++ (intercalate ", " keeps) ++ "\n\n" ++ (attemptSecurity machine instructions validDropset) +passSecurity machine instructions items = "You keep: " ++ (intercalate ", " keeps) ++ "\n\n" ++ successResponse where + env = (machine, instructions) dropsets = powerList items - validDropset = head $ filter (passesSecurity machine instructions) dropsets + validDropset = head $ filter (\ds -> runReader (passesSecurity ds) env) dropsets + successResponse = (runReader (attemptSecurity validDropset) env) keeps = items \\ validDropset -passesSecurity :: Machine -> [String] -> [String] -> Bool -passesSecurity machine instructions drops = not ("Alert" `isInfixOf` output) - where output = attemptSecurity machine instructions drops +passesSecurity :: [String] -> CachedMachine Bool +passesSecurity drops = + do output <- attemptSecurity drops + return $ not ("Alert" `isInfixOf` output) + +attemptSecurity :: [String] -> CachedMachine String +attemptSecurity drops = + do let dropCommands = map ("drop " ++ ) drops + output <- runCachedMachine dropCommands + return output + +runCachedMachine :: [String] -> CachedMachine String +runCachedMachine dropCommands = + do (machine, instructions) <- ask + let (_, _, output) = runMachine (encodeCommands (instructions ++ dropCommands ++ ["north"])) machine + return $ decodeOutput output + -attemptSecurity :: Machine -> [String] -> [String] -> String -attemptSecurity machine instructions drops = decodeOutput output - where dropCommands = map ("drop " ++ ) drops - (_, _, output) = runMachine (encodeCommands (instructions ++ dropCommands ++ ["north"])) machine runCommand :: [Integer] -> [String] -> (Machine, String) runCommand mem inputs = ( machine, decodeOutput output )