Create a list of sublists of a given list - list

I need a function that returns a list of all possible sublists, without skipping elements, e.g. sublists [1,2,3,4] should return [[1,2,3,4],[1,2,3] etc.] but the list should NOT contain [1,2,4].
My current "solution" is
>sublists :: [Integer] -> [[Integer]]
>sublists [] = [[]]
>sublists (x:xs) = [x:ys | ys <- sublists xs] ++ sublists xs
which does include [1,2,4]
Thanks in advance
EDIT: Found a solution (with a little help of my friend)
Looks a bit clumsy but it works
>sublists :: [Integer] -> [[Integer]]
>sublists [] = [[]]
>sublists (x:xs) = subs [] (x:xs) ++ sublists xs
> where
> subs :: [Integer] -> [Integer] -> [[Integer]]
> subs xs [] = [xs]
> subs xs (a:as) = (xs ++ [a]) : (subs (xs ++ [a]) as)

Data.List contains both inits and tails. What you want is the inits of each member of the tails list (or possibly vice-versa, but see later for the reason why this way round is better)
sublists = concatMap inits . tails
> sublists [1,2,3,4]
[[],[1],[1,2],[1,2,3],[1,2,3,4],[],[2],[2,3],[2,3,4],[],[3],[3,4],[],[4],[]]
If you prefer, you might want to get rid of all the null lists:
sublists = filter (not . null) . concatMap inits . tails
Or if you prefer to avoid generating the null lists in the first place:
sublists = concatMap (tail . inits) . tails
The result of inits always starts with the empty list, while the result of tails always ends with the empty list. So tail . inits is safe because tail will never be applied to an empty list; it just returns the result without the leading empty list. inits [] just returns [[]], so the last empty list from tails gets dropped.

Related

How to find all minimum elements in a list of tuples?

How can I find all the minimum elements in a list? Right now I have a list of tuples, i.e.
[(10,'a'),(5,'b'),(1,'c'),(8,'d'),(1,'e')]
So I want the output which is all the minimum elements of the list, in a new list. For example
[(1,'c'),(1,'e')]
I tried
minimumBy (comparing fst) xs
but that only returns the first minimum element.
After you obtain the minimum of the first value, we can filter the list on these items. Because you here want to retrieve a list of minimum items, we can cover the empty list as well by returning an empty list:
minimumsFst :: Ord a => [(a, b)] -> [(a, b)]
minimumsFst [] = []
minimumsFst xs = filter ((==) minfst . fst) xs
where minfst = minimum (map fst xs)
For example:
Prelude> minimumsFst [(10,'a'),(5,'b'),(1,'c'),(8,'d'),(1,'e')]
[(1,'c'),(1,'e')]
Oneliner. The key is sorting.
Prelude Data.List> let a = [(1,'c'),(2,'b'),(1,'w')]
Prelude Data.List> (\xs#((m,_):_) -> takeWhile ((== m) . fst ) xs) . sortOn fst $ a
[(1,'c'),(1,'w')]
Here's a solution that works in one pass (most other answers here do two passes: one to find the minimum value and one to filter on it), and doesn't rely on how the sorting functions are implemented to be efficient.
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Foldable (foldl')
minimumsBy :: forall a. (a -> a -> Ordering) -> [a] -> [a]
minimumsBy _ [] = []
minimumsBy f (x:xs) = postprocess $ foldl' go (x, id) xs
where
go :: (a, [a] -> [a]) -> a -> (a, [a] -> [a])
go acc#(x, xs) y = case f x y of
LT -> acc
EQ -> (x, xs . (y:))
GT -> (y, id)
postprocess :: (a, [a] -> [a]) -> [a]
postprocess (x, xs) = x:xs []
Note that the [a] -> [a] type I'm using here is called a difference list, aka a Hughes list.
You tried
minimumBy (comparing fst) xs
which can also be written as
= head . sortBy (comparing fst) $ xs
= head . sortOn fst $ xs
= head . head . group . sortOn fst $ xs
= head . head . groupBy ((==) `on` fst) . sortOn fst $ xs
This returns just the first element instead of the list of them, so just drop that extra head to get what you want:
= head . groupBy ((==) `on` fst) . sortOn fst $ xs
Of course having head is no good since it'll error out on the [] input. Instead, we can use the safe option,
= concat . take 1 . groupBy ((==) `on` fst) . sortOn fst $ xs
By the way any solution that calls minimum is also unsafe for the empty input list:
> head []
*** Exception: Prelude.head: empty list
> minimum []
*** Exception: Prelude.minimum: empty list
but takeWhile is safe:
> takeWhile undefined []
[]
edit: thanks to laziness, the overall time complexity of the final version should still be O(n) even in the worst case.
You can do it easily too with foldr:
minimumsFst :: Ord a => [(a, b)] -> [(a, b)]
minimumsFst xs = go (minfst xs) xs
where
go mn ls = foldr (\(x, y) rs -> if (x == mn) then (x,y) : rs else rs) [] xs
minfst ls = minimum (map fst ls)
with your example:
minimumsFst [(10,'a'),(5,'b'),(1,'c'),(8,'d'),(1,'e')]
=> [(1,'c'),(1,'e')]

Haskell: List manipulation

I want to write a function which takes a input list and manipulates it in the following way:
Step 1: Take the first element of the list and the last element of the list and put it together in a sublist.
Step 2: Take the second element of the list and the second last element of the list and put it together in the next sublist.
Step 3: Take the third element of the list and the third last element of the
list and put it together in next sublist.
Continue this according to the same scheme (for a list of n elements)...
If the number of elements of the input list is odd the n/2 element of the input list will be added as last sublist of the output list.
Example:
[1,2,3,4,5,6,7]
-- should be transformed to
[[1,7],[2,6],[3,5],[4]]
I already wrote a function which takes every 2 elements of a list and puts it together in sublists and I am wondering if this code might help me with my problem above:
g2 :: [a] -> [[a]]
g2 [] = []
g2 (x1:x2:xs) = [x1,x2]: g2 xs
g2 xs = [xs]
Here's one that does it in one pass:
pairs :: [a] -> [[a]]
pairs xs = fst (go xs xs) where
go (x:xs) (_:_:ys) = f x (go xs ys)
go (x:xs) [_] = ([[x]],xs)
go xs [] = ([],xs)
f x (xs,y:ys) = ([x,y]:xs,ys)
How does it work? Let's look at the first two arguments of go first, and in particular this line:
go (x:xs) (_:_:ys) = f x (go xs ys)
Those two arguments are both from the same list (xs), but we take 2 items off of one, and only one off of the other. Why? So we know when we hit the halfway point. Look at this function for comparison:
halfway xs = go xs xs
where
go (_:xs) (_:_:ys) = go xs ys
go xs _ = xs
>>> halfway [1..6]
[4,5,6]
Now, once we get to the halfway point we'll need to "zip" it with the other list. But it needs to be in reverse! How do we do this? A handy way to reverse any function in one pass is to first write it as a fold. Here's zip written as a fold:
zip = foldr (\x k (y:ys) -> (x,y) : k ys) (const [])
To "reverse" it, you just apply is as a foldl rather than as a foldr (you also have to flip the closure).
For our uses, we basically build up the base as we go (in the form of k). So no our function looks like this:
pairs :: [a] -> [[a]]
pairs xs = go xs xs (const []) where
go (y:ys) (_:_:zs) k = go ys zs (f y k)
go (y:ys) [_] k = [y] : k ys
go ys [] k = k ys
f x k (y:ys) = [x,y] : k ys -- same `f` as from `zip`
There's still one problem: the list is returned in the wrong order. To fix this, we replace the list with a difference list, and swap the order of the appends.
Finally, we un-CPS the function, and we get the above.
Here's one using transpose
import Data.List
g2 xs =
transpose [take (x + y) xs, take x (reverse xs)]
where (x, y) = (length xs) `divMod` 2
Note that we have to use drop 1 instead of tail here to avoid errors for odd-length lists.
g2 :: [a] -> [[a]]
g2 [] = []
g2 xs = [first xs] ++ (g2 . drop 1 $ init xs)
where first (x:[]) = [x]
first xs = [head xs, last xs]
Two more, the second is using unfoldr:
pair xs = take (length xs `div` 2) $ zip xs (reverse xs)
-- Note: uses tuples instead of lists
import Data.List
pairs2 = unfoldr (\xs ->
if length xs < 2
then Nothing
else Just ([head xs, last xs], init.tail $ xs))
xs = [2,3,4,7,6]
pair xs -- [(2,6),(3,7)]
pair2 xs -- [[2,6],[3,7]]

fail to use foldl to reverse a list in Haskell

I know how to use recursion to reverse a list, but I am trying to use foldl to make it more efficient. My code is as follow:
reverse list = foldl (++) [] (map (\x -> [x]) list)
When running it in GHCi, it returns the same list as input. What goes wrong? I also try to finish it by foldr but it does not show any change.
foldl passes the accumulator as the first argument to the function. ++ concatenates the first argument to the second, but, to reverse a list, you need to concatenate the second to the first. You can do this using flip (++):
Prelude> let reverse list = foldl (flip (++)) [] (map (\x -> [x]) list)
Prelude> reverse [1..5]
[5,4,3,2,1]
Instead of first converting all elements of the list to singleton lists (which is expensive as well), you can use the cons (:) function:
reverse :: Foldable t => t a -> [a]
reverse = foldl (flip (:)) []
So here we use flip (:) :: [a] -> a -> [a] as fold function. It takes a tail [a] and a head a, and constructs a list with the head as first element and the tail as last element.
So what happens is:
foldl (flip (:)) [] [1,4,2,5]
-> foldl (flip (:)) (1:[]) [4,2,5]
-> foldl (flip (:)) (4:1:[]) [2,5]
-> foldl (flip (:)) (2:4:1:[]) [5]
-> foldl (flip (:)) (5:2:4:1:[]) []
-> (5:2:4:1:[])
-> [5,2,4,1]

Remove duplicate but keep the order

rmdup :: [Int] -> [Int]
rmdup [] = []
rmdup (x:xs) | x `elem` xs = rmdup xs
| otherwise = x: rmdup xs
The code above removes duplicate from a list of Integer but it removes the first occurrence and keeps the second one. For instance:
rmdup [1,2,3,1,4]
will result:
[2,3,1,4]
How can I change it to keep the order and yield this: [1,2,3,4]? Note, I don't want to use built-in functions.
How about the following? This avoids the crazily inefficient acc ++ [x] and also to reverse the given list twice:
rmdup :: Eq a => [a] => [a]
rmdup xs = rmdup' [] xs
where
rmdup' acc [] = []
rmdup' acc (x:xs)
| x `elem` acc = rmdup' acc xs
| otherwise = x : rmdup' (x:acc) xs
One way to achieve what you want is to pass the input list in the reverse order and once when the computation is finished then reverse the result again. Although, this solution is not efficient.
rmdup :: [Int] -> [Int]
rmdup xs = reverse $ rmdup' (reverse xs)
where
rmdup' [] = []
rmdup' (x:xs) | x `elem` xs = rmdup' xs
| otherwise = x: rmdup' xs
Demo:
ghci> rmdup [1,2,3,1,4]
[1,2,3,4]
You want to ignore those later occurrences of an element if you saw it before, then you need to record what you have seen, looks like foldl or foldl' is what you are looking for.
Here is a possible implementation:
import Data.List (foldl')
rmdup :: (Eq a) => [a] -> [a]
rmdup = foldl' step []
where step acc x
| x `elem` acc = acc
| otherwise = acc++[x]
Since elem is O(n), the solutions based on using it to check each element are O(n^2).
The "standard" efficient solution to the duplicates problem is to sort the list before checking for duplicates. Here, since we need to preserve elements, we have to be a bit more careful.
import Data.List
import Data.Ord
rmdupSorted :: Eq b => [(a,b)] -> [(a,b)]
rmdupSorted (x#(_,xb):xs#((_,yb):_)) | xb == yb = rmdupSorted xs
| otherwise = x : rmdupSorted xs
rmdupSorted xs = xs -- 0 or 1 elements
rmdup :: Ord a => [a] -> [a]
rmdup = map snd . sort . rmdupSorted . sortBy (comparing snd) . zip [0..]
main = print $ rmdup [1,2,3,4,5,4,6,1,7]
Assuming that the sortBy function is a stable sort, the rmdup function will remove all the duplicate occurrences of any element but for the one occurring last. If sortBy is not stable, then rmdup will remove all the occurrences but for an unspecified one (i.e., rmdup [1,2,1] could return [1,2] instead of [2,1].).
Complexity is now O(n log n).
We now need to rewrite the above without library functions, as the OP requested. I will leave this as an exercise to the reader. :-P

Generating all contiguous sublists of a list

I'm kinda new to Haskell and I'm trying to generate all contiguous sublists of a list.
I current have the following:
listSublists :: [a] -> [[a]]
listSublists [] = [[]]
listSublists xs = [xs] ++ listSublists (init xs)
I know the function above would generate sublists with the last element removed but I've no idea how to finish my pseudocode.
My pseudocode is basically,
Take the whole complete list, remove tail. Pass xs of (x:xs) into
listSublists
For example, xs = [1,2,3]
[xs] ++ listSublists (init xs) would generate [1,2,3,4], [1,2,3], [1,2], [1], [] and I'm trying to continue that with passing in [2,3,4] as xs until the list is exhausted.
Can someone give me some pointers? Or am I thinking in a completely wrong way?
The listSublists function that you have is functionally almost identical to
the inits
function. You are on the right track, in that you can currently list all of
the prefixes of a given list.
What you want to ask is "what is a sublist of a list?" One answer is that it
is a suffix of a prefix of the list (i.e. chop off some portion from the
end of a list and then chop off some elements off the front of that list, and
you have one of the contiguous sublists).
So, if you have your prefixes, then what you want is a way to generate all
the suffixes of a given prefix (i.e. of some list). So, if you have
prefixes :: [a] -> [[a]]
prefixes [] = [[]]
prefixes xs = [xs] ++ prefixes (init xs)
you also want a corresponding function suffixes
suffixes :: [a] -> [[a]]
suffixes [] = [[]]
suffixes xs = [xs] ++ suffixes (??? xs)
I will leave it to you to figure out what to use for ???. With these two
functions, you then just take all the prefixes, and produce all the suffixes
to get all the contiguous sublists
allSublists :: [a] -> [[a]]
allSublists = concat . map suffixes . prefixes
You may want to remove all of the empty lists that will be in the result set,
as they are not that interesting of a case.
All sublists (not necessarily contiguous):
sublists [] = [[]]
sublists (x:xs) = [x:sublist | sublist <- sublists xs] ++ sublists xs
Only contiguous sublists:
nub $ concat $ map tails $ inits ls
or
(:) [] $ filter (\x -> length x /= 0) $ concat $ map tails $ inits ls