Reorganizing a list of lists - haskell

How to solve this problem?
The problem is to reorder the list-of-lists of doubles:
[ [a, b, c], [aa, bb, cc] ]
into this:
[ [a, aa], [b, bb], [c, cc] ]
After poking about I came up with the following (a function that increasingly diggs deeper and deeper into sublists, taking their head and joining them together):
organize xs = organize' xs head
--recursive function (type stolen from ghci)
organize':: [[a]] -> ([a] -> b) -> [b]
organize' [] f = []
organize' xs f = (map f xs)++(organize' xs (f . tail)
This doesn't work too good (which I thought it did) - in my joy of success I completely missed the error:
Exception: Prelude.head: empty list

Your mention of "doubles" implies that you want a list of 2-tuples (ie, "doubles"), rather than a list of 2-element lists. (Or perhaps this wording was particular to my Function Programming 101 lecturer!)
In which case, zip does exactly this:
zip [1, 2, 3] [4, 5, 6] = [(1,4),(2,5),(3,6)]
If you do need a list of 2-element lists (instead of tuples), you can use zipWith:
organize [xs,ys] = zipWith (\x y -> [x,y]) xs ys
Or are you looking for something that will work with any number of lists? In that case (as others have commented) transpose from Data.List is what you're after:
transpose [[1,2,3],[4,5,6]] = [[1,4],[2,5],[3,6]]

Related

Take symmetrical pairs, of different numbers from list

I have a list like this:
[(2,3),(2,5),(2,7),(3,2),(3,4),(3,6),(4,3),(4,5),(4,7),(5,2),(5,4),(5,6),(6,3),(6,5),(6,7),(7,2),(7,4),(7,6)]
The digits are from [2..7]. I want to take a set where there are any symmetrical pairs. e.g. [(1,2),(2,1)], but those two numbers aren't used again in the set. An example would be:
[(3,6),(6,3),(2,5),(5,2),(4,7),(7,4)]
I wanted to first put symmetric pairs together as I thought it might be easier to work with so i created this function, which actually creates the pairs and puts them in another list
g xs = [ (y,x):(x,y):[] | (x,y) <- xs ]
with which the list turns to this:
[[(3,2),(2,3)],[(5,2),(2,5)],[(7,2),(2,7)],[(2,3),(3,2)],[(4,3),(3,4)],[(6,3),(3,6)],[(3,4),(4,3)],[(5,4),(4,5)],[(7,4),(4,7)],[(2,5),(5,2)],[(4,5),(5,4)],[(6,5),(5,6)],[(3,6),(6,3)],[(5,6),(6,5)],[(7,6),(6,7)],[(2,7),(7,2)],[(4,7),(7,4)],[(6,7),(7,6)]]
Then from here I was hoping to somehow remove duplicates.
I made a function that will look at all of the fst elements of all of the pairs:
flatList xss = [ x | xs <- xss, (x,y) <- xs ]
to use with another function to remove the duplicates.
h (x:xs) | (fst (head x)) `elem` (flatList xs) = h xs
| otherwise = (head x):(last x):(h xs)
which gives me the list
[(3,6),(6,3),(5,6),(6,5),(2,7),(7,2),(4,7),(7,4),(6,7),(7,6)]
which has duplicate numbers. That function only takes into account the first element of the first pair in the list of lists,the problem is when I also take into account the first element of the second pair (or the second element of the first pair):
h (x:xs) | (fst (head x)) `elem` (flatList xs) || (fst (last x)) `elem` (flatList xs) = h xs
| otherwise = (head x):(last x):(h xs)
I only get these two pairs:
[(6,7),(7,6)]
I see that the problem is that this method of deleting duplicates grabs the last repeated element, and would work with a list of digits, but not a list of pairs, as it misses pairs it needs to take.
Is there another way to solve this, or an alteration I could make?
It probably makes more sense to use a 2-tuple of 2-tuples in your list comprehension, since that makes it more easy to do pattern matching, and thus "by contract" enforces the fact that there are two items. We thus can construct 2-tuples that contain the 2-tuples with:
g :: Eq a => [(a, a)] -> [((a, a), (a, a))]
g xs = [ (t, s) | (t#(x,y):ts) <- tails xs, let s = (y, x), elem s ts ]
Here the elem s ts checks if the "swapped" 2-tuple occurs in the rest of the list.
Then we still need to filter the elements. We can make use of a function that uses an accumulator for the thus far obtained items:
h :: Eq a => [((a, a), (a, a))] -> [(a, a)]
h = go []
where go _ [] = []
go seen ((t#(x, y), s):xs)
| notElem x seen && notElem y seen = t : s : go (x:y:seen) xs
| otherwise = go seen xs
For the given sample input, we thus get:
Prelude Data.List> (h . g) [(2,3),(2,5),(2,7),(3,2),(3,4),(3,6),(4,3),(4,5),(4,7),(5,2),(5,4),(5,6),(6,3),(6,5),(6,7),(7,2),(7,4),(7,6)]
[(2,3),(3,2),(4,5),(5,4),(6,7),(7,6)]
after reading a few times your question, I got an elegant solution to your problem. Thinking that if you have a list of pairs without any repeated number, you can get the list of swapped pairs easily, solving your problem. So your problem can be reduce to given a list, get the list of all pairs using each number just one.
For a given list, there are many solutions to this, ex: for [1,2,3,4] valid solutions are: [(2,4),(4,2),(1,3),(3,1)] and [(2,3),(3,2),(1,4),(4,1)], etc... The approach here is:
take a permutation if the original list (say [1,4,3,2])
pick one element for each half and pair them together (for simplicity, you can pick consecutive elements too)
for each pair, create a the swapped pair and put all together
By doing so you end up with a list of non repeating numbers of pairs and its symmetric. More over, looping around all permutaitons, you can get all the solutions to your problem.
import Data.List (permutations, splitAt)
import Data.Tuple (swap)
-- This function splits a list by the half of the length
splitHalf :: [a] -> ([a], [a])
splitHalf xs = splitAt (length xs `quot` 2) xs
-- This zip a pair of list into a list of pairs
zipHalfs :: ([a], [a]) -> [(a,a)]
zipHalfs (xs, ys) = zip xs ys
-- Given a list of tuples, creates a larger list with all tuples and all swapped tuples
makeSymetrics :: [(a,a)] -> [(a,a)]
makeSymetrics xs = foldr (\t l -> t:(swap t):l) [] xs
-- This chain all of the above.
-- Take all permutations of xs >>> for each permutations >>> split it in two >>> zip the result >>> make swapped pairs
getPairs :: [a] -> [[(a,a)]]
getPairs xs = map (makeSymetrics . zipHalfs . splitHalf) $ permutations xs
>>> getPairs [1,2,3,4]
[[(1,3),(3,1),(2,4),(4,2)],[(2,3),(3,2),(1,4),(4,1)] ....

Haskell's "permutations" function defined oddly

If I wanted to find the permutations of a list, I know that the number of permutations is given by the multinomial coefficient. For example, "MISSISSIPPI" has 11 letters, 'S' appears 4 times, 'I' appears 4 times, 'P' appears twice and 'M' appears once. So the number of permutations of "MISSISSIPPI" is equal to 11!/(4!4!2!) = 34650.
If I load up GHCi and write:
ghci> import Data.List
ghci> permutations [1,2,3]
It will return
[[1,2,3],[2,1,3],[3,2,1],[2,3,1],[3,1,2],[1,3,2]]
as expected.
But if I write
ghci> permutations [1,0,0]
it will now return
[[1,0,0],[0,1,0],[0,0,1],[0,0,1],[0,1,0],[1,0,0]]
... which is very disappointing. As there are three elements, and two of them occur twice, one would hope for there only to be 6!/2! = 3 permutations, namely
[[1,0,0],[0,1,0],[0,0,1]]
rather than the six generated by treating each element of the list as distinct.
1) Why does Haskell implement "permutations" in the way described above (i.e. treating all elements of a list as distinct?)
2) Are there any standard library functions that calculate the permutations of a list in the "true" sense of permutations?
Remember that permutations has type
permutations :: [a] -> [[a]]
That means that it satisfies the free theorem
permutations . map f = (map . map) f . permutations
for all functions f. Since you can change the elements of the argument list arbitrarily without affecting the structure of the result list, permutations must really be a function on the indices of the original list, rather than the elements.
So what permutations is really doing --- what it must do --- is calculate all permutations of the indices of the argument list, then apply each of those permutations to the list and return the results. (I.e.,
permutations xn = (map . map) (xn!!) (permutations [0..length xn - 1])
for finite xn).
Mathematical appendix:
Since
xn = map (xn!!) (zipWith const [0..] xn)
for all xn, any function with permutations's type must satisfy
permutations xn
= permutations (map (xn!!) (zipWith const [0..] xn)
= (map . map) (xn!!) (permutations (zipWith const [0..] xn))
by the equation above for xn and the free theorem for permutations. So any function with permutations's type must operate only on the indices of the input list[1].
[1] Technically you can violate this by using seq. But only for input lists that contain undefined as an element, which isn't true in your case.
1 - Why does Haskell implement "permutations" in the way described above (i.e. treating all elements of a list as distinct?)
It is a design question and should be studied in deep. permutation treats the elements of the list as if they were all different from each other. You can do permutations [0, 0, 0] and you'll yet get a list of lists of size 6.
2 - Are there any standard library functions that calculate the permutations of a list in the "true" sense of permutations?
Yes, you have the Math.Combinat.Permutations, but you can easily create your own definition filtering the unique combinations with a complexity of O(n * log n) using sets, taking account that nub is known by being very slow:
module Main where
import Data.List (permutations)
import qualified Data.Set as Set
nubOrd :: (Ord a) => [a] -> [a]
nubOrd xs = go Set.empty xs where
go s (x:xs)
| x `Set.member` s = go s xs
| otherwise = x : go (Set.insert x s) xs
go _ _ = []
permutations' :: (Ord a) => [a] -> [[a]]
permutations' = nubOrd . permutations
Where permutations' [1, 0, 0] gives [[1, 0, 0], [0, 1, 0], [0, 0, 1]].
Why does Haskell implement "permutations" in the way described above (i.e. treating all elements of a list as distinct?)
Because otherwise, the type would have to be:
permutations :: Eq a => [a] -> [[a]]
and then we could permute only things that have an Eq instance. But I remember I had something like
permutations [(+), subtract, (*), (/)]
in some Project Euler code ....
Here is a slightly rearranged Daniel Fischer's solution:
inserts :: [a] -> [a] -> [[a]]
inserts (x:xs) (y:ys) = map (x:) (inserts xs (y:ys)) ++ map (y:) (inserts (x:xs) ys)
inserts xs ys = [xs ++ ys]
uniqPerms :: Ord a => [a] -> [[a]]
uniqPerms = foldM inserts [] . group . sort

How do I split a list into sublists at certain points?

How do I manually split [1,2,4,5,6,7] into [[1],[2],[3],[4],[5],[6],[7]]? Manually means without using break.
Then, how do I split a list into sublists according to a predicate? Like so
f even [[1],[2],[3],[4],[5],[6],[7]] == [[1],[2,3],[4,5],[6,7]]
PS: this is not homework, and I've tried for hours to figure it out on my own.
To answer your first question, this is rather an element-wise transformation than a split. The appropriate function to do this is
map :: (a -> b) -> [a] -> [b]
Now, you need a function (a -> b) where b is [a], as you want to transform an element into a singleton list containing the same type. Here it is:
mkList :: a -> [a]
mkList a = [a]
so
map mkList [1,2,3,4,5,6,7] == [[1],[2],...]
As for your second question: If you are not allowed (homework?) to use break, are you then allowed to use takeWhile and dropWhile which form both halves of the result of break.
Anyway, for a solution without them ("manually"), just use simple recursion with an accumulator:
f p [] = []
f p (x:xs) = go [x] xs
where go acc [] = [acc]
go acc (y:ys) | p y = acc : go [y] ys
| otherwise = go (acc++[y]) ys
This will traverse your entire list tail recursively, always remembering what the current sublist is, and when you reach an element where p applies, outputting the current sublist and starting a new one.
Note that go first receives [x] instead of [] to provide for the case where the first element already satisfies p x and we don't want an empty first sublist to be output.
Also, this operates on the original list ([1..7]) instead of [[1],[2]...]. But you can use it on the transformed one as well:
> map concat $ f (odd . head) [[1],[2],[3],[4],[5],[6],[7]]
[[1,2],[3,4],[5,6],[7]]
For the first, you can use a list comprehension:
>>> [[x] | x <- [1,2,3,4,5,6]]
[[1], [2], [3], [4], [5], [6]]
For the second problem, you can use the Data.List.Split module provided by the split package:
import Data.List.Split
f :: (a -> Bool) -> [[a]] -> [[a]]
f predicate = split (keepDelimsL $ whenElt predicate) . concat
This first concats the list, because the functions from split work on lists and not list of lists. The resulting single list is the split again using functions from the split package.
First:
map (: [])
Second:
f p xs =
let rs = foldr (\[x] ~(a:r) -> if (p x) then ([]:(x:a):r) else ((x:a):r))
[[]] xs
in case rs of ([]:r) -> r ; _ -> rs
foldr's operation is easy enough to visualize:
foldr g z [a,b,c, ...,x] = g a (g b (g c (.... (g x z) ....)))
So when writing the combining function, it is expecting two arguments, 1st of which is "current element" of a list, and 2nd is "result of processing the rest". Here,
g [x] ~(a:r) | p x = ([]:(x:a):r)
| otherwise = ((x:a):r)
So visualizing it working from the right, it just adds into the most recent sublist, and opens up a new sublist if it must. But since lists are actually accessed from the left, we keep it lazy with the lazy pattern, ~(a:r). Now it works even on infinite lists:
Prelude> take 9 $ f odd $ map (:[]) [1..]
[[1,2],[3,4],[5,6],[7,8],[9,10],[11,12],[13,14],[15,16],[17,18]]
The pattern for the 1st argument reflects the peculiar structure of your expected input lists.

Merge multiple lists if condition is true

I've been trying to wrap my head around this for a while now, but it seems like my lack of Haskell experience just won't get me through it. I couldn't find a similar question here on Stackoverflow (most of them are related to merging all sublists, without any condition)
So here it goes. Let's say I have a list of lists like this:
[[1, 2, 3], [3, 5, 6], [20, 21, 22]]
Is there an efficient way to merge lists if some sort of condition is true? Let's say I need to merge lists that share at least one element. In case of example, result would be:
[[1, 2, 3, 3, 5, 6], [20, 21, 22]]
Another example (when all lists can be merged):
[[1, 2], [2, 3], [3, 4]]
And it's result:
[[1, 2, 2, 3, 3, 4]]
Thanks for your help!
I don't know what to say about efficiency, but we can break down what's going on and get several different functionalities at least. Particular functionalities might be optimizable, but it's important to clarify exactly what's needed.
Let me rephrase the question: For some set X, some binary relation R, and some binary operation +, produce a set Q = {x+y | x in X, y in X, xRy}. So for your example, we might have X being some set of lists, R being "xRy if and only if there's at least one element in both x and y", and + being ++.
A naive implementation might just copy the set-builder notation itself
shareElement :: Eq a => [a] -> [a] -> Bool
shareElement xs ys = or [x == y | x <- xs, y <- ys]
v1 :: (a -> a -> Bool) -> (a -> a -> b) -> [a] -> [b]
v1 (?) (<>) xs = [x <> y | x <- xs, y <- xs, x ? y]
then p = v1 shareElement (++) :: Eq a => [[a]] -> [[a]] might achieve what you want. Except it probably doesn't.
Prelude> p [[1], [1]]
[[1,1],[1,1],[1,1],[1,1]]
The most obvious problem is that we get four copies: two from merging the lists with themselves, two from merging the lists with each other "in both directions". The problem occurs because List isn't the same as Set so we can't kill uniques. Of course, that's an easy fix, we'll just use Set everywhere
import Data.Set as Set
v2 :: (a -> a -> Bool) -> (a -> a -> b) -> Set.Set a -> Set.Set b
v2 (?) (<>) = Set.fromList . v1 (?) (<>) . Set.toList
So we can try again, p = v2 (shareElementonSet.toList) Set.union with
Prelude Set> p $ Set.fromList $ map Set.fromList [[1,2], [2,1]]
fromList [fromList [1,2]]
which seems to work. Note that we have to "go through" List because Set can't be made an instance of Monad or Applicative due to its Ord constraint.
I'd also note that there's a lot of lost behavior in Set. For instance, we fight either throwing away order information in the list or having to handle both x <> y and y <> x when our relation is symmetric.
Some more convenient versions can be written like
v3 :: Monoid a => (a -> a -> Bool) -> [a] -> [a]
v3 r = v2 r mappend
and more efficient ones can be built if we assume that the relationship is, say, an equality relation since then instead of having an O(n^2) operation we can do it in O(nd) where d is the number of partitions (cosets) of the relation.
Generally, it's a really interesting problem.
I just happened to write something similar here: Finding blocks in arrays
You can just modify it so (although I'm not too sure about the efficiency):
import Data.List (delete, intersect)
example1 = [[1, 2, 3], [3, 5, 6], [20, 21, 22]]
example2 = [[1, 2], [2, 3], [3, 4]]
objects zs = map concat . solve zs $ [] where
areConnected x y = not . null . intersect x $ y
solve [] result = result
solve (x:xs) result =
let result' = solve' xs [x]
in solve (foldr delete xs result') (result':result) where
solve' xs result =
let ys = filter (\y -> any (areConnected y) result) xs
in if null ys
then result
else solve' (foldr delete xs ys) (ys ++ result)
OUTPUT:
*Main> objects example1
[[20,21,22],[3,5,6,1,2,3]]
*Main> objects example2
[[3,4,2,3,1,2]]

Delete list elements by looking on another list

I have two lists. One list contains some random data and other list contains the index of first list which needs to be deleted.
For example, let us consider two lists:
let a = [3,4,5,6,6,7,8]
let b = [1,3]
Then, the resultant output should be [3,5,6,7,8]. The number 4 and 6 are deleted since they are on index positions 1 and 3 respectively.
I'm new to Haskell, so finding it difficult to find the solution.
Update: Following code makes it work
import Data.List
dele :: Eq a => [a] -> [Int] -> [a]
dele [] _ = []
dele x [] = x
dele x (y:ys) = dele (delete (x !! y) x) ys
I was just wondering, is there a way to solve it through map/fold way ?
deleteByIndex :: (Enum a, Eq a, Num a) => [a] -> [b] -> [b]
deleteByIndex r = map snd . filter (\(i, _) -> notElem i r) . zip [0..]
[0..] produces an infinite list [0, 1, 2, 3, ...]
zip constructs a list of pairs with the values of this list and your input list in the form [(0,x), (1, y), ...]
filter takes a function a -> Bool. The lambda checks if the index (first element of the pair) is in your input list r.
map snd returns the second element of each pair of the zip list.
zip,filter, map and notElem are documented here
Off the top of my head:
removeByIndex :: [Integer] -> [a] -> [a]
removeByIndex indices = map snd . filter notInIndices . zip [0..]
where notInIndices (i,_) = i `notElem` indices
An alternative answer using the lens library which has received considerable attention recently
import Control.Lens
>let a = [3,4,5,6,6,7,8]
>let b = [1,3]
>a^..elements (`notElem`b)
[3,5,6,7,8]
(^..) is jus the infix for of toListOf which can be used to traverse a structure and make a list out of its parts. The elements function just lets you choose which ones to include.
Other options are 'traverse' to traverse a traversables, 'both' to traverse a (,) and they compose together with (.) so traverse.both would traverse [(1,2), (3,4)] for example.
[(1,2), (3,4)]^..traverse.both
[1,2,3,4]

Resources