cf. 今日の一行 – loopの列挙
trail
はすでにたどったノードのリスト p
と次にたどるノードの候補 q
を受け取って,全ての経路を列挙する。「次のノード」がスタートと同じならそこでそのループは終わり。違うなら再帰的にノードをたどる。
各ノードは比較さえできればいいので Eq a
にした。入出力の関係で結局は文字列になってるけど。
module Main (main) where import Data.List (intersperse) import System (getArgs) trail :: (Eq a) => [a] -> [a] -> [[a]] trail p q = concat $ map trail' q where trail' q1 | head p == q1 = [ p ++ [q1] ] | otherwise = trail (p ++ [q1]) $ filter (q1/=) q trailLoop :: (Eq a) => a -> [a] -> [[a]] trailLoop s = trail [s] enumLoops :: (Eq a) => [a] -> [[a]] enumLoops nodes = concat $ map (flip trailLoop nodes) nodes showLoop :: [String] -> String showLoop = concat . intersperse " -> " main :: IO () main = do nodes <- getArgs mapM_ (putStrLn . showLoop) $ enumLoops nodes
実行例
D:\>runghc enumLoops.hs 1 2 3 1 -> 1 1 -> 2 -> 1 1 -> 2 -> 3 -> 1 1 -> 3 -> 1 1 -> 3 -> 2 -> 1 2 -> 1 -> 2 2 -> 1 -> 3 -> 2 2 -> 2 2 -> 3 -> 1 -> 2 2 -> 3 -> 2 3 -> 1 -> 2 -> 3 3 -> 1 -> 3 3 -> 2 -> 1 -> 3 3 -> 2 -> 3 3 -> 3
ノードが1つ増えるとループはぐっと増える。
D:\>runghc enumLoops.hs 1 2 3 4 1 -> 1 1 -> 2 -> 1 1 -> 2 -> 3 -> 1 1 -> 2 -> 3 -> 4 -> 1 1 -> 2 -> 4 -> 1 1 -> 2 -> 4 -> 3 -> 1 1 -> 3 -> 1 1 -> 3 -> 2 -> 1 1 -> 3 -> 2 -> 4 -> 1 1 -> 3 -> 4 -> 1 1 -> 3 -> 4 -> 2 -> 1 1 -> 4 -> 1 1 -> 4 -> 2 -> 1 1 -> 4 -> 2 -> 3 -> 1 1 -> 4 -> 3 -> 1 1 -> 4 -> 3 -> 2 -> 1 2 -> 1 -> 2 2 -> 1 -> 3 -> 2 2 -> 1 -> 3 -> 4 -> 2 2 -> 1 -> 4 -> 2 2 -> 1 -> 4 -> 3 -> 2 2 -> 2 2 -> 3 -> 1 -> 2 2 -> 3 -> 1 -> 4 -> 2 2 -> 3 -> 2 2 -> 3 -> 4 -> 1 -> 2 2 -> 3 -> 4 -> 2 2 -> 4 -> 1 -> 2 2 -> 4 -> 1 -> 3 -> 2 2 -> 4 -> 2 2 -> 4 -> 3 -> 1 -> 2 2 -> 4 -> 3 -> 2 3 -> 1 -> 2 -> 3 3 -> 1 -> 2 -> 4 -> 3 3 -> 1 -> 3 3 -> 1 -> 4 -> 2 -> 3 3 -> 1 -> 4 -> 3 3 -> 2 -> 1 -> 3 3 -> 2 -> 1 -> 4 -> 3 3 -> 2 -> 3 3 -> 2 -> 4 -> 1 -> 3 3 -> 2 -> 4 -> 3 3 -> 3 3 -> 4 -> 1 -> 2 -> 3 3 -> 4 -> 1 -> 3 3 -> 4 -> 2 -> 1 -> 3 3 -> 4 -> 2 -> 3 3 -> 4 -> 3 4 -> 1 -> 2 -> 3 -> 4 4 -> 1 -> 2 -> 4 4 -> 1 -> 3 -> 2 -> 4 4 -> 1 -> 3 -> 4 4 -> 1 -> 4 4 -> 2 -> 1 -> 3 -> 4 4 -> 2 -> 1 -> 4 4 -> 2 -> 3 -> 1 -> 4 4 -> 2 -> 3 -> 4 4 -> 2 -> 4 4 -> 3 -> 1 -> 2 -> 4 4 -> 3 -> 1 -> 4 4 -> 3 -> 2 -> 1 -> 4 4 -> 3 -> 2 -> 4 4 -> 3 -> 4 4 -> 4