module Commons where import GHC.IO.Handle (isEOF) import Data.Hashable (Hashable (hash), hashWithSalt) import Data.HashMap.Strict (HashMap, empty, insert, singleton, union) data Instruction = ILeft | IRight deriving Eq instance Hashable Instruction where hashWithSalt s ILeft = s + hash False hashWithSalt s IRight = s + hash True data Network = Network { instructions :: [Instruction], nodes :: HashMap (String, Instruction) String } parseInstructions :: String -> [Instruction] parseInstructions ('L': t) = ILeft: parseInstructions t parseInstructions ('R': t) = IRight: parseInstructions t parseInstructions [] = [] parseNode :: String -> HashMap (String, Instruction) String parseNode [a, b, c, ' ', '=', ' ', '(', d, e, f, ',', ' ', g, h, i, ')'] = insert ([a, b, c], ILeft) [d, e, f] $ singleton ([a, b, c], IRight) [g, h, i] parseNodes :: IO (HashMap (String, Instruction) String) parseNodes = do done <- isEOF if done then return empty else do line <- getLine let node = parseNode line otherNodes <- parseNodes let newNodes = node `union` otherNodes return newNodes parse :: IO Network parse = do instructionsRaw <- getLine getLine let instructions = parseInstructions instructionsRaw nodes <- parseNodes return Network {instructions = instructions, nodes = nodes}