https://wiki.haskell.org/api.php?action=feedcontributions&user=B1nj0y&feedformat=atomHaskellWiki - User contributions [en]2021-07-27T15:59:35ZUser contributionsMediaWiki 1.27.4https://wiki.haskell.org/index.php?title=99_questions/Solutions/19&diff=6206899 questions/Solutions/192017-08-12T07:07:55Z<p>B1nj0y: </p>
<hr />
<div>(**) Rotate a list N places to the left.<br />
<br />
Hint: Use the predefined functions length and (++).<br />
<br />
<haskell><br />
rotate [] _ = []<br />
rotate xs 0 = xs<br />
rotate (x:xs) (n+1) = rotate (xs ++ [x]) n<br />
rotate xs n = rotate xs (length xs + n)<br />
</haskell><br />
<br />
(Note that this solution uses [http://en.wikibooks.org/wiki/Haskell/Pattern_matching#n.2Bk_patterns n+k-patterns] which are [http://www.haskell.org/onlinereport/haskell2010/haskellli2.html#x3-5000 removed] from Haskell 2010.) <br />
<br />
There are two separate cases:<br />
* If n > 0, move the first element to the end of the list n times.<br />
* If n < 0, convert the problem to the equivalent problem for n > 0 by adding the list's length to n.<br />
<br />
or using cycle:<br />
<haskell><br />
rotate xs n = take len . drop (n `mod` len) . cycle $ xs<br />
where len = length xs<br />
</haskell><br />
<br />
or using list comprehension (only works for sequential increasing elements):<br />
<haskell><br />
rotate :: (Enum a) => [a] -> Int -> [a]<br />
rotate xs n = [(f n) .. last xs] ++ [head xs .. (f (n-1))]<br />
where f k = xs !! (k `mod` length xs)<br />
</haskell><br />
<br />
or without mod:<br />
<haskell><br />
rotate xs n = take (length xs) $ drop (length xs + n) $ cycle xs<br />
</haskell><br />
<br />
or<br />
<br />
<haskell><br />
rotate xs n = if n >= 0 then<br />
drop n xs ++ take n xs<br />
else let l = ((length xs) + n) in<br />
drop l xs ++ take l xs<br />
</haskell><br />
<br />
or<br />
<br />
<haskell><br />
rotate xs n | n >= 0 = drop n xs ++ take n xs<br />
| n < 0 = drop len xs ++ take len xs<br />
where len = n+length xs<br />
</haskell><br />
<br />
or calculate the position at first:<br />
<br />
<haskell><br />
rotate xs n = let i = if n < 0 then length xs + n else n<br />
in drop i xs ++ take i xs<br />
</haskell><br />
<br />
or<br />
<br />
<haskell><br />
rotate xs n = drop nn xs ++ take nn xs<br />
where <br />
nn = n `mod` length xs<br />
</haskell><br />
<br />
Using a simple splitAt trick<br />
<haskell><br />
rotate xs n<br />
| n < 0 = rotate xs (n+len)<br />
| n > len = rotate xs (n-len)<br />
| otherwise = let (f,s) = splitAt n xs in s ++ f<br />
where len = length xs<br />
</haskell><br />
<br />
Without using <hask>length</hask>:<br />
<haskell><br />
rotate xs n<br />
| n > 0 = (reverse . take n . reverse $ xs) ++ (reverse . drop n . reverse $ xs)<br />
| n <= 0 = (drop (negate n) xs) ++ (take (negate n) xs)<br />
</haskell><br />
<br />
A much simpler solution without using <hask>length</hask> that is very similar to the first solution:<br />
<haskell><br />
rotate :: [a] -> Int -> [a]<br />
rotate [] _ = []<br />
rotate x 0 = x<br />
rotate x y<br />
| y > 0 = rotate (tail x ++ [head x]) (y-1)<br />
| otherwise = rotate (last x : init x) (y+1)<br />
</haskell><br />
<br />
<br />
[[Category:Programming exercise spoilers]]</div>B1nj0yhttps://wiki.haskell.org/index.php?title=99_questions/Solutions/19&diff=6206799 questions/Solutions/192017-08-12T07:07:35Z<p>B1nj0y: </p>
<hr />
<div>(**) Rotate a list N places to the left.<br />
<br />
Hint: Use the predefined functions length and (++).<br />
<br />
<haskell><br />
rotate [] _ = []<br />
rotate xs 0 = xs<br />
rotate (x:xs) (n+1) = rotate (xs ++ [x]) n<br />
rotate xs n = rotate xs (length xs + n)<br />
</haskell><br />
<br />
(Note that this solution uses [http://en.wikibooks.org/wiki/Haskell/Pattern_matching#n.2Bk_patterns n+k-patterns] which are [http://www.haskell.org/onlinereport/haskell2010/haskellli2.html#x3-5000 removed] from Haskell 2010.) <br />
<br />
There are two separate cases:<br />
* If n > 0, move the first element to the end of the list n times.<br />
* If n < 0, convert the problem to the equivalent problem for n > 0 by adding the list's length to n.<br />
<br />
or using cycle:<br />
<haskell><br />
rotate xs n = take len . drop (n `mod` len) . cycle $ xs<br />
where len = length xs<br />
</haskell><br />
<br />
or using list comprehension (only works for sequential increasing elements):<br />
<haskell><br />
rotate :: (Enum a) => [a] -> Int -> [a]<br />
rotate xs n = [(f n) .. last xs] ++ [head xs .. (f (n-1))]<br />
where f k = xs !! (k `mod` length xs)<br />
</haskell><br />
<br />
or without mod:<br />
<haskell><br />
rotate xs n = take (length xs) $ drop (length xs + n) $ cycle xs<br />
</haskell><br />
<br />
or<br />
<br />
<haskell><br />
rotate xs n = if n >= 0 then<br />
drop n xs ++ take n xs<br />
else let l = ((length xs) + n) in<br />
drop l xs ++ take l xs<br />
</haskell><br />
<br />
or<br />
<br />
<haskell><br />
rotate xs n | n >= 0 = drop n xs ++ take n xs<br />
| n < 0 = drop len xs ++ take len xs<br />
where len = n+length xs<br />
</haskell><br />
<br />
or calculate the position(index) at first:<br />
<br />
<haskell><br />
rotate xs n = let i = if n < 0 then length xs + n else n<br />
in drop i xs ++ take i xs<br />
</haskell><br />
<br />
or<br />
<br />
<haskell><br />
rotate xs n = drop nn xs ++ take nn xs<br />
where <br />
nn = n `mod` length xs<br />
</haskell><br />
<br />
Using a simple splitAt trick<br />
<haskell><br />
rotate xs n<br />
| n < 0 = rotate xs (n+len)<br />
| n > len = rotate xs (n-len)<br />
| otherwise = let (f,s) = splitAt n xs in s ++ f<br />
where len = length xs<br />
</haskell><br />
<br />
Without using <hask>length</hask>:<br />
<haskell><br />
rotate xs n<br />
| n > 0 = (reverse . take n . reverse $ xs) ++ (reverse . drop n . reverse $ xs)<br />
| n <= 0 = (drop (negate n) xs) ++ (take (negate n) xs)<br />
</haskell><br />
<br />
A much simpler solution without using <hask>length</hask> that is very similar to the first solution:<br />
<haskell><br />
rotate :: [a] -> Int -> [a]<br />
rotate [] _ = []<br />
rotate x 0 = x<br />
rotate x y<br />
| y > 0 = rotate (tail x ++ [head x]) (y-1)<br />
| otherwise = rotate (last x : init x) (y+1)<br />
</haskell><br />
<br />
<br />
[[Category:Programming exercise spoilers]]</div>B1nj0yhttps://wiki.haskell.org/index.php?title=99_questions/Solutions/19&diff=6206699 questions/Solutions/192017-08-12T07:06:59Z<p>B1nj0y: </p>
<hr />
<div>(**) Rotate a list N places to the left.<br />
<br />
Hint: Use the predefined functions length and (++).<br />
<br />
<haskell><br />
rotate [] _ = []<br />
rotate xs 0 = xs<br />
rotate (x:xs) (n+1) = rotate (xs ++ [x]) n<br />
rotate xs n = rotate xs (length xs + n)<br />
</haskell><br />
<br />
(Note that this solution uses [http://en.wikibooks.org/wiki/Haskell/Pattern_matching#n.2Bk_patterns n+k-patterns] which are [http://www.haskell.org/onlinereport/haskell2010/haskellli2.html#x3-5000 removed] from Haskell 2010.) <br />
<br />
There are two separate cases:<br />
* If n > 0, move the first element to the end of the list n times.<br />
* If n < 0, convert the problem to the equivalent problem for n > 0 by adding the list's length to n.<br />
<br />
or using cycle:<br />
<haskell><br />
rotate xs n = take len . drop (n `mod` len) . cycle $ xs<br />
where len = length xs<br />
</haskell><br />
<br />
or using list comprehension (only works for sequential increasing elements):<br />
<haskell><br />
rotate :: (Enum a) => [a] -> Int -> [a]<br />
rotate xs n = [(f n) .. last xs] ++ [head xs .. (f (n-1))]<br />
where f k = xs !! (k `mod` length xs)<br />
</haskell><br />
<br />
or without mod:<br />
<haskell><br />
rotate xs n = take (length xs) $ drop (length xs + n) $ cycle xs<br />
</haskell><br />
<br />
or<br />
<br />
<haskell><br />
rotate xs n = if n >= 0 then<br />
drop n xs ++ take n xs<br />
else let l = ((length xs) + n) in<br />
drop l xs ++ take l xs<br />
</haskell><br />
<br />
or<br />
<br />
<haskell><br />
rotate xs n | n >= 0 = drop n xs ++ take n xs<br />
| n < 0 = drop len xs ++ take len xs<br />
where len = n+length xs<br />
</haskell><br />
<br />
or calculate the postion(index) at first:<br />
<br />
<haskell><br />
rotate xs n = let i = if n < 0 then length xs + n else n<br />
in drop i xs ++ take i xs<br />
</haskell><br />
<br />
or<br />
<br />
<haskell><br />
rotate xs n = drop nn xs ++ take nn xs<br />
where <br />
nn = n `mod` length xs<br />
</haskell><br />
<br />
Using a simple splitAt trick<br />
<haskell><br />
rotate xs n<br />
| n < 0 = rotate xs (n+len)<br />
| n > len = rotate xs (n-len)<br />
| otherwise = let (f,s) = splitAt n xs in s ++ f<br />
where len = length xs<br />
</haskell><br />
<br />
Without using <hask>length</hask>:<br />
<haskell><br />
rotate xs n<br />
| n > 0 = (reverse . take n . reverse $ xs) ++ (reverse . drop n . reverse $ xs)<br />
| n <= 0 = (drop (negate n) xs) ++ (take (negate n) xs)<br />
</haskell><br />
<br />
A much simpler solution without using <hask>length</hask> that is very similar to the first solution:<br />
<haskell><br />
rotate :: [a] -> Int -> [a]<br />
rotate [] _ = []<br />
rotate x 0 = x<br />
rotate x y<br />
| y > 0 = rotate (tail x ++ [head x]) (y-1)<br />
| otherwise = rotate (last x : init x) (y+1)<br />
</haskell><br />
<br />
<br />
[[Category:Programming exercise spoilers]]</div>B1nj0yhttps://wiki.haskell.org/index.php?title=99_questions/Solutions/5&diff=6206599 questions/Solutions/52017-08-11T12:06:13Z<p>B1nj0y: </p>
<hr />
<div>(*) Reverse a list.<br />
<br />
<haskell><br />
reverse :: [a] -> [a]<br />
reverse = foldl (flip (:)) []<br />
</haskell><br />
<br />
The standard definition, found in the prelude, is concise, but not very readable. Another way to define reverse is:<br />
<br />
<haskell><br />
reverse :: [a] -> [a]<br />
reverse [] = []<br />
reverse (x:xs) = reverse xs ++ [x]<br />
</haskell><br />
<br />
However this definition is more wasteful than the one in Prelude as it repeatedly reconses the result as it is accumulated. The following variation avoids that, and thus computationally closer to the Prelude version.<br />
<br />
<haskell><br />
reverse :: [a] -> [a]<br />
reverse list = reverse' list []<br />
where<br />
reverse' [] reversed = reversed<br />
reverse' (x:xs) reversed = reverse' xs (x:reversed)<br />
</haskell><br />
<br />
And my favorite, although the most unreadable for sure :)<br />
<br />
<haskell><br />
myReverse'' :: [a] -> [a]<br />
myReverse'' xs = foldr (\x fId empty -> fId (x : empty)) id xs []<br />
</haskell><br />
<br />
Another foldl version:<br />
<haskell><br />
myReverse''' :: [a] -> [a]<br />
myReverse''' = foldl (\a x -> x:a) []<br />
</haskell><br />
<br><br />
<br />
[[Category:Programming exercise spoilers]]</div>B1nj0yhttps://wiki.haskell.org/index.php?title=99_questions/Solutions/5&diff=6206499 questions/Solutions/52017-08-11T12:05:12Z<p>B1nj0y: </p>
<hr />
<div>(*) Reverse a list.<br />
<br />
<haskell><br />
reverse :: [a] -> [a]<br />
reverse = foldl (flip (:)) []<br />
</haskell><br />
<br />
The standard definition, found in the prelude, is concise, but not very readable. Another way to define reverse is:<br />
<br />
<haskell><br />
reverse :: [a] -> [a]<br />
reverse [] = []<br />
reverse (x:xs) = reverse xs ++ [x]<br />
</haskell><br />
<br />
However this definition is more wasteful than the one in Prelude as it repeatedly reconses the result as it is accumulated. The following variation avoids that, and thus computationally closer to the Prelude version.<br />
<br />
<haskell><br />
reverse :: [a] -> [a]<br />
reverse list = reverse' list []<br />
where<br />
reverse' [] reversed = reversed<br />
reverse' (x:xs) reversed = reverse' xs (x:reversed)<br />
</haskell><br />
<br />
And my favorite, although the most unreadable for sure :)<br />
<br />
<haskell><br />
myReverse'' :: [a] -> [a]<br />
myReverse'' xs = foldr (\x fId empty -> fId (x : empty)) id xs []<br />
</haskell><br />
<br><br />
<br />
Another foldl version:<br />
<haskell><br />
myReverse''' :: [a] -> [a]<br />
myReverse''' = foldl (\a x -> x:a) []<br />
</haskell><br />
<br />
[[Category:Programming exercise spoilers]]</div>B1nj0y