Reputation: 1291
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
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
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
Reputation: 22530
You can simply do:
rotate n l = drop n l ++ take n l
to achieve the same without cycle.
Upvotes: 4