+-- import Debug.Trace
+
+import Intcode
+
+import qualified Data.Text.IO as TIO
+import qualified Data.Text as T
+import Data.Char
+import Data.List
+
+main :: IO ()
+main = do
+ text <- TIO.readFile "data/advent25.txt"
+ let mem = parseMachineMemory text
+ print $ length mem
+ (machine, instructions, items) <- runPreamble mem
+ -- runGameM machine instructions
+ putStrLn $ passSecurity machine instructions items
+
+runPreamble :: [Integer] -> IO (Machine, [String], [String])
+runPreamble mem =
+ do
+ instr <- TIO.readFile "data/advent25-instructions.txt"
+ let instructions = lines $ T.unpack instr
+ -- runGame mem $ lines $ T.unpack instructions
+ let (machine, _output) = runCommand mem instructions
+ let (_s, _machine1, output1) = runMachine (encodeCommands (instructions ++ ["inv"])) machine
+ putStrLn $ decodeOutput output1
+ let items = extractItems $ decodeOutput output1
+ -- print items
+ return (machine, instructions, items)
+
+
+encodeCommands :: [String] -> [Integer]
+encodeCommands cmds = map (fromIntegral . ord) $ concat $ map (++ "\n") cmds
+
+decodeOutput :: [Integer] -> String
+decodeOutput = map (chr . fromIntegral)
+
+extractItems :: String -> [String]
+extractItems text = items
+ where candidates = lines text
+ items = map (drop 2) $ filter (isPrefixOf "- ") candidates
+
+
+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)
+ where
+ dropsets = powerList items
+ validDropset = head $ filter (passesSecurity machine instructions) dropsets
+ keeps = items \\ validDropset
+
+passesSecurity :: Machine -> [String] -> [String] -> Bool
+passesSecurity machine instructions drops = not ("Alert" `isInfixOf` output)
+ where output = attemptSecurity machine instructions drops
+
+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 )
+ where (_state, machine, output) = runProgram inputCodes mem
+ inputCodes = encodeCommands inputs
+
+runGame :: [Integer] -> [String] -> IO ()
+runGame mem inputs =
+ do let (_, outputs) = runCommand mem inputs
+ putStrLn outputs
+ nextIn <- getLine
+ runGame mem (inputs ++ [nextIn])
+
+runGameM :: Machine -> [String] -> IO ()
+runGameM machine inputs =
+ do nextIn <- getLine
+ let (_s, machine1, output1) = runMachine (encodeCommands (inputs ++ [nextIn])) machine
+ putStrLn $ decodeOutput output1
+ runGameM machine1 (inputs ++ [nextIn])