Floyd's cycle-finding algorithm

From HaskellWiki
Revision as of 16:38, 17 October 2011 by Monoidal (talk | contribs) (elements must be unique, e.g. findCycle $ cycle [0,1,0])
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

This is a Haskell impelementation of Floyd's cycle-finding algorithm for finding cycles in lists.

findCycle :: Eq a => [a] -> ([a],[a])
findCycle xxs = fCycle xxs xxs
  where fCycle (x:xs) (_:y:ys)
         | x == y              = fStart xxs xs
         | otherwise           = fCycle xs ys
        fCycle _      _        = (xxs,[]) -- not cyclic
        fStart (x:xs) (y:ys)
         | x == y              = ([], x:fLength x xs)
         | otherwise           = let (as,bs) = fStart xs ys in (x:as,bs)
        fLength x (y:ys)
         | x == y              = []
         | otherwise           = y:fLength x ys

This function is essentially the inverse of cycle. I.e. if xs and ys don't have a common suffix, their elements are unique and both are finite, we have that

findCycle (xs ++ cycle ys) == (xs,ys)