# 99 questions/Solutions/19

### From HaskellWiki

< 99 questions | Solutions(Difference between revisions)

Citizen428 (Talk | contribs) m |
m |
||

Line 50: | Line 50: | ||

| otherwise = let (f,s) = splitAt n xs in s ++ f | | otherwise = let (f,s) = splitAt n xs in s ++ f | ||

where len = length xs | where len = length xs | ||

+ | </haskell> | ||

+ | |||

+ | Without using <hask>length</hask>: | ||

+ | <haskell> | ||

+ | rotate xs n | ||

+ | | n > 0 = (reverse . take n . reverse $ xs) ++ (reverse . drop n . reverse $ xs) | ||

+ | | n <= 0 = (drop (negate n) xs) ++ (take (negate n) xs) | ||

</haskell> | </haskell> |

## Revision as of 11:57, 14 January 2011

(**) Rotate a list N places to the left.

Hint: Use the predefined functions length and (++).

rotate [] _ = [] rotate l 0 = l rotate (x:xs) (n+1) = rotate (xs ++ [x]) n rotate l n = rotate l (length l + n)

There are two separate cases:

- If n > 0, move the first element to the end of the list n times.
- If n < 0, convert the problem to the equivalent problem for n > 0 by adding the list's length to n.

or using cycle:

rotate xs n = take len . drop (n `mod` len) . cycle $ xs where len = length xs

or

rotate xs n = if n >= 0 then drop n xs ++ take n xs else let l = ((length xs) + n) in drop l xs ++ take l xs

or

rotate xs n | n >= 0 = drop n xs ++ take n xs | n < 0 = drop len xs ++ take len xs where len = n+length xs

rotate xs n = drop nn xs ++ take nn xs where nn = n `mod` length xs

Using a simple splitAt trick

rotate xs n | n < 0 = rotate xs (n+len) | n > len = rotate xs (n-len) | otherwise = let (f,s) = splitAt n xs in s ++ f where len = length xs

length

rotate xs n | n > 0 = (reverse . take n . reverse $ xs) ++ (reverse . drop n . reverse $ xs) | n <= 0 = (drop (negate n) xs) ++ (take (negate n) xs)