50 lines
2.1 KiB
Haskell
50 lines
2.1 KiB
Haskell
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
|
|
{-# HLINT ignore "Use tuple-section" #-}
|
|
module Commons where
|
|
|
|
import Data.List.Utils (split)
|
|
import GHC.IO.Handle (isEOF)
|
|
import Data.Map (Map, assocs, member, (!), fromList, empty, insert, toList, notMember)
|
|
|
|
|
|
data Module = Broadcaster { outputs :: [String] } |
|
|
FlipFlop { state :: Bool, outputs :: [String] } |
|
|
Conjonction { inputs :: Map String Bool, outputs :: [String] } deriving (Show)
|
|
type Modules = Map String Module
|
|
|
|
|
|
parseModule :: String -> [String] -> (String, Module)
|
|
parseModule "broadcaster" outputs = ("broadcaster", Broadcaster {outputs = outputs})
|
|
parseModule ('%': name) outputs = (name, FlipFlop {state = False, outputs = outputs})
|
|
parseModule ('&': name) outputs =
|
|
(name, Conjonction {inputs = empty, outputs = outputs})
|
|
|
|
computeInputs'' :: String -> [String] -> Modules -> Modules
|
|
computeInputs'' _ [] modules = modules
|
|
computeInputs'' name (h: t) modules
|
|
| notMember h modules = computeInputs'' name t modules
|
|
| otherwise =
|
|
let output = modules ! h
|
|
in case output of
|
|
Conjonction i o -> computeInputs'' name t $ insert h Conjonction {inputs = insert name False i, outputs = o}
|
|
modules
|
|
_ -> computeInputs'' name t modules
|
|
|
|
computeInputs' :: [(String, Module)] -> Modules -> Modules
|
|
computeInputs' [] modules = modules
|
|
computeInputs' ((name, m): t) modules = computeInputs' t $ computeInputs'' name (outputs m) modules
|
|
|
|
computeInputs :: Modules -> Modules
|
|
computeInputs modules = computeInputs' (toList modules) modules
|
|
|
|
parseModules :: [(String, Module)] -> IO Modules
|
|
parseModules otherModules = do done <- isEOF
|
|
if done then return $ computeInputs $ fromList otherModules
|
|
else do line <- getLine
|
|
let (rawName: rawOutputs: _) = split " -> " line
|
|
let cmodule = parseModule rawName $ split ", " rawOutputs
|
|
parseModules $ otherModules ++ [cmodule]
|
|
|
|
parse :: IO Modules
|
|
parse = parseModules []
|