Bradley
Bradley

Reputation: 1291

Rotating a list about an index

I have a list, lets say [1, 2, 3, 4, 5] and I have to rotate the list at an index.

For example:

rotate 2 [1, 2, 3, 4, 5] gives [3, 4, 5, 1, 2]

Through researching online, I came across the cycle function which gets around the problem of losing the list when you drop it, but I feel as if I would benefit far more from producing my own working solution in terms of understanding, even if it is less efficient than a library function. The working solution I have is below:

rotate :: Int -> [a] -> [a]
rotate _ [] = []
rotate n l  = take (length l) $ drop n (cycle l)

Could you suggest, without code, alternative ways of achieving this solution so I can have a crack at those? As I'm stuck without ideas now I have seen this way of doing it!

Cheers

Upvotes: 1

Views: 126

Answers (3)

knightmare
knightmare

Reputation: 103

...what about straightforward solution?

rotate :: Int -> [a] -> [a]
rotate 0 xs = xs
rotate _ [] = []
rotate n (x:xs) = rotate (pred n) (xs ++ [x])

Upvotes: 0

effectfully
effectfully

Reputation: 12725

Since here already exists a solution with code, I'll post another version:

rotate :: Int -> [a] -> [a]
rotate n [] = []
rotate n xs = xs2 ++ xs1
    where (xs1, xs2) = splitAt (n `rem` length xs) xs

Some tests:

main = do
    print $ rotate 0 [1..5] -- [1,2,3,4,5]
    print $ rotate 2 [1..5] -- [3,4,5,1,2]
    print $ rotate 5 [1..5] -- [1,2,3,4,5]
    print $ rotate 7 [1..5] -- [3,4,5,1,2]

Upvotes: 1

thor
thor

Reputation: 22530

You can simply do:

rotate n l  = drop n l ++ take n l 

to achieve the same without cycle.

Upvotes: 4

Related Questions