module GenCircuit (Node, EndPoint (..), GenCircuit, newNode, connect, generate) where import Control.Monad.State import Text.Printf type Node = Int data EndPoint = L Node | R Node | X deriving (Show, Eq, Ord) type GenCircuit = State (Int, [(EndPoint,EndPoint)]) newNode :: GenCircuit Node newNode = do (i, conn) <- get put (i+1, conn) return i connect :: EndPoint -> EndPoint -> GenCircuit () connect from to = do (i, conn) <- get put (i, (from,to):conn) return () generate :: GenCircuit () -> String generate m = h X ++ ":\n" ++ concat [f i ++ if i == n-1 then ":\n" else ",\n" | i <- [0..n-1]] ++ g X where (n,conn) = execState m (0,[]) f i = printf "%s%s0#%s%s" (g (L i)) (g (R i)) (h (L i)) (h (R i)) g ep = head [showEndPoint from | (from,to) <- conn, to==ep] h ep = head [showEndPoint to | (from,to) <- conn, from==ep] showEndPoint :: EndPoint -> String showEndPoint (L n) = show n ++ "L" showEndPoint (R n) = show n ++ "R" showEndPoint X = "X" test = generate $ do n <- newNode connect X (R n) connect (L n) (L n) connect (R n) X {- 0R: 0LX0#0LX: 0R -}