5 import qualified Data.Text.IO as TIO
6 import qualified Data.Text as T
12 text <- TIO.readFile "data/advent25.txt"
13 let mem = parseMachineMemory text
15 (machine, instructions, items) <- runPreamble mem
16 -- runGameM machine instructions
17 putStrLn $ passSecurity machine instructions items
19 runPreamble :: [Integer] -> IO (Machine, [String], [String])
22 instr <- TIO.readFile "data/advent25-instructions.txt"
23 let instructions = lines $ T.unpack instr
24 -- runGame mem $ lines $ T.unpack instructions
25 let (machine, _output) = runCommand mem instructions
26 let (_s, _machine1, output1) = runMachine (encodeCommands (instructions ++ ["inv"])) machine
27 putStrLn $ decodeOutput output1
28 let items = extractItems $ decodeOutput output1
30 return (machine, instructions, items)
33 encodeCommands :: [String] -> [Integer]
34 encodeCommands cmds = map (fromIntegral . ord) $ concat $ map (++ "\n") cmds
36 decodeOutput :: [Integer] -> String
37 decodeOutput = map (chr . fromIntegral)
39 extractItems :: String -> [String]
40 extractItems text = items
41 where candidates = lines text
42 items = map (drop 2) $ filter (isPrefixOf "- ") candidates
45 powerList :: [a] -> [[a]]
47 powerList (x:xs) = powerList xs ++ map (x:) (powerList xs)
50 passSecurity :: Machine -> [String] -> [String] -> String
51 passSecurity machine instructions items =
52 "You keep: " ++ (intercalate ", " keeps) ++ "\n\n" ++ (attemptSecurity machine instructions validDropset)
54 dropsets = powerList items
55 validDropset = head $ filter (passesSecurity machine instructions) dropsets
56 keeps = items \\ validDropset
58 passesSecurity :: Machine -> [String] -> [String] -> Bool
59 passesSecurity machine instructions drops = not ("Alert" `isInfixOf` output)
60 where output = attemptSecurity machine instructions drops
62 attemptSecurity :: Machine -> [String] -> [String] -> String
63 attemptSecurity machine instructions drops = decodeOutput output
64 where dropCommands = map ("drop " ++ ) drops
65 (_, _, output) = runMachine (encodeCommands (instructions ++ dropCommands ++ ["north"])) machine
67 runCommand :: [Integer] -> [String] -> (Machine, String)
68 runCommand mem inputs = ( machine, decodeOutput output )
69 where (_state, machine, output) = runProgram inputCodes mem
70 inputCodes = encodeCommands inputs
72 runGame :: [Integer] -> [String] -> IO ()
74 do let (_, outputs) = runCommand mem inputs
77 runGame mem (inputs ++ [nextIn])
79 runGameM :: Machine -> [String] -> IO ()
80 runGameM machine inputs =
82 let (_s, machine1, output1) = runMachine (encodeCommands (inputs ++ [nextIn])) machine
83 putStrLn $ decodeOutput output1
84 runGameM machine1 (inputs ++ [nextIn])