-- Dijkstras Dutch Flag Problem -- ============================ -- Eine Liste mit rot, weiss oder blau gefaerbten Objekten -- soll so umsortiert werden, dass zunaechst alle roten, -- dann alle weissen und schliesslich alle blauen Objekte -- auftreten. Dabei soll die relative Ordnung der gleichfarbigen -- Objekte untereinander erhalten bleiben. import DifferenceLists data Dutch a = Red a | White a | Blue a deriving (Eq, Show) dutch :: [Dutch a] -> [Dutch a] dutch ds = rs ++ ws ++ bs where (rs, ws, bs) = distribute ds ([],[],[]) distribute :: [Dutch a] -> ([Dutch a], [Dutch a], [Dutch a]) -> ([Dutch a], [Dutch a], [Dutch a]) distribute [] (rs,ws,bs) = (rs, ws, bs) distribute (d:ds) (rs,ws,bs) = add d (distribute ds (rs,ws,bs)) add :: Dutch a -> ([Dutch a], [Dutch a], [Dutch a]) -> ([Dutch a], [Dutch a], [Dutch a]) add (Red x) (rs,ws,bs) = ((Red x):rs, ws, bs) add (White x) (rs,ws,bs) = (rs, (White x):ws, bs) add (Blue x) (rs,ws,bs) = (rs, ws, (Blue x):bs) bspliste len = zipWith ($) (cycle [Blue, White, Red, Blue, White, Red, Red, Blue, White]) [1..len] -- -- Version mit Differenzlisten -- -- dutch2 :: [Dutch a] -> [Dutch a] dutch2 ds = toList (dutchDL ds) dutchDL :: [Dutch a] -> DL (Dutch a) dutchDL ds = (append rs (append ws bs)) where (rs,ws,bs) = distributeDL ds (empty, empty, empty) distributeDL :: [Dutch a] -> (DL (Dutch a), DL (Dutch a), DL (Dutch a)) -> (DL (Dutch a), DL (Dutch a), DL (Dutch a)) distributeDL [] (rs,ws,bs) = (rs, ws, bs) distributeDL (d:ds) (rs,ws,bs) = addDL d (distributeDL ds (rs,ws,bs)) addDL :: Dutch a -> (DL (Dutch a), DL (Dutch a), DL (Dutch a)) -> (DL (Dutch a), DL (Dutch a), DL (Dutch a)) addDL (Red x) (rs,ws,bs) = ((Red x) `cons` rs, ws, bs) addDL (White x) (rs,ws,bs) = (rs, (White x)`cons` ws, bs) addDL (Blue x) (rs,ws,bs) = (rs, ws, (Blue x)`cons` bs)