Difference between revisions of "99 questions/Solutions/17"
< 99 questions | Solutions
Jump to navigation
Jump to search
(cleanup) |
Blazedaces (talk | contribs) (Added another solution) |
||
Line 31: | Line 31: | ||
split xs 0 = ([], xs) |
split xs 0 = ([], xs) |
||
split (x:xs) n = let (f,l) = split xs (n-1) in (x : f, l) |
split (x:xs) n = let (f,l) = split xs (n-1) in (x : f, l) |
||
+ | </haskell> |
||
+ | |||
+ | A similar solution using foldl: |
||
+ | |||
+ | <haskell> |
||
+ | split :: [a] -> Int -> ([a], [a]) |
||
+ | split [] _ = ([], []) |
||
+ | split list n |
||
+ | | n < 0 = (list, []) |
||
+ | | otherwise = (first output, second output) |
||
+ | where output = foldl (\acc e -> if third acc > 0 then (first acc ++ [e], second acc, third acc - 1) else (first acc, second acc ++ [e], third acc)) ([], [], n) list |
||
+ | </haskell> |
||
+ | |||
+ | Note that for the above code to work you must define your own first, second, and third functions for tuples containing three elements like so: |
||
+ | |||
+ | <haskell> |
||
+ | first :: (a, b, c) -> a |
||
+ | first (x, _, _) = x |
||
+ | |||
+ | second :: (a, b, c) -> b |
||
+ | second (_, y, _) = y |
||
+ | |||
+ | third :: (a, b, c) -> c |
||
+ | third (_, _, z) = z |
||
</haskell> |
</haskell> |
Revision as of 09:01, 16 November 2011
(*) Split a list into two parts; the length of the first part is given.
Do not use any predefined predicates.
Solution using take
and drop
:
split xs n = (take n xs, drop n xs)
Or even simpler using splitAt
:
split = flip splitAt
But these should clearly be considered "predefined predicates". Alternatively, we have the following recursive solution:
split :: [a] -> Int -> ([a], [a])
split [] _ = ([], [])
split l@(x : xs) n | n > 0 = (x : ys, zs)
| otherwise = ([], l)
where (ys,zs) = split xs (n - 1)
The same solution as above written more cleanly:
split :: [a] -> Int -> ([a], [a])
split xs 0 = ([], xs)
split (x:xs) n = let (f,l) = split xs (n-1) in (x : f, l)
A similar solution using foldl:
split :: [a] -> Int -> ([a], [a])
split [] _ = ([], [])
split list n
| n < 0 = (list, [])
| otherwise = (first output, second output)
where output = foldl (\acc e -> if third acc > 0 then (first acc ++ [e], second acc, third acc - 1) else (first acc, second acc ++ [e], third acc)) ([], [], n) list
Note that for the above code to work you must define your own first, second, and third functions for tuples containing three elements like so:
first :: (a, b, c) -> a
first (x, _, _) = x
second :: (a, b, c) -> b
second (_, y, _) = y
third :: (a, b, c) -> c
third (_, _, z) = z