Concatenating every third list - list

I have a big list of lists. And I want to concat every third list into each other. Like such
let xss = [[1,2,3],[1,2,3],[1,2,3],
[4,5,6],[4,5,6],[4,5,6],
[7,8,9],[7,8,9],[7,8,9]]
someFunk xss = [[1,2,3,1,2,3,1,2,3],
[4,5,6,4,5,6,4,5,6],
[7,8,9,7,8,9,7,8,9]]
Is there a way of doing this?

Just for bikeshedding purposes, I think I would write something like this:
import Data.List.Split
someFunk = map concat . chunksOf 3
It's concise, and I think it also reads a lot like your English description. It uses the split package.

You could try something like this:
someFunk :: [[a]] -> [[a]]
someFunk (x:y:z:zs) = (x ++ y ++ z) : someFunk zs
someFunk (x:y:ys) = (x ++ y) : someFunk ys
someFunk (x:xs) = x : someFunk xs
someFunk _ = []
Using pattern matching, you check for a list with at least three lists, join them and recursively call it on the remainder of the list. If the list count is not an exact multiple of 3, the subsequent patterns still allow you to concatenate the next 3 while available.
Demo

Related

removing duplicates from a list in haskell

I am trying to delete consecutive duplicates in a list; for instance, given the list [1,2,2,3,4], it the function I need must return [1,3,4].
My code at the end of the question, however, doesn't work if trailing duplicates are in list, like in [1,2,3,4,4].
I also want to do it in as simple terms as possible, how can I do this?
myCom :: Eq a => [a] -> [a]
myCom (x:y:ys#(z:_))
| x == y = myCom ys
| otherwise = x : myCom (y:ys)
myCom ys = ys
The first pattern match you have only catches lists with at least 3 elements.
That is why when the duplicates are at the end of the list when
myCom [4,4]
is called it simply uses
myCom ys = ys
and returns itself. You can catch this by defining myCom for lists with at least 2 elements as below (you werent't using z anyway):
myCom (x:y:ys)
| x == y = myCom ys
| otherwise = x : myCom (y:ys)
myCom ys = ys
This gives
myCom [1,2,2,3,4,4] = [1,3]
There is still an issue with 3 (an odd number) consecutive numbers. For example we get:
myCom [1,2,2,2] = [1,2]
but I understand that this is desired behavior.
I would use Maybe to represent a length of one as a success condition. This works well with Haskell's pattern-matching syntax. You can then use group (from Data.List) and filter out the Nothings using catMaybe (from Data.Maybe) :
myCom = catMaybes . map lenOne . group
where lenOne [x] = Just x
lenOne _ = Nothing
From a comment I see that the function Data.Set.nub just does what the OP asks.
However, my first attempt to solve the problem was the following, which only removes duplicates if they are consecutive (e.g. [1,2,1,2,1,2] is not changed):
concat $ filter (\x -> length x == 1) $ Data.List.group [1,2,3,4,4]
I hope this answer could be useful to some random user ending up on this page.

Haskell - Removing adjacent duplicates from a list

I'm trying to learn haskell by solving some online problems and training exercises.
Right now I'm trying to make a function that'd remove adjacent duplicates from a list.
Sample Input
"acvvca"
"1456776541"
"abbac"
"aabaabckllm"
Expected Output
""
""
"c"
"ckm"
My first though was to make a function that'd simply remove first instance of adjacent duplicates and restore the list.
module Test where
removeAdjDups :: (Eq a) => [a] -> [a]
removeAdjDups [] = []
removeAdjDups [x] = [x]
removeAdjDups (x : y : ys)
| x == y = removeAdjDups ys
| otherwise = x : removeAdjDups (y : ys)
*Test> removeAdjDups "1233213443"
"122133"
This func works for first found pairs.
So now I need to apply same function over the result of the function.
Something I think foldl can help with but I don't know how I'd go about implementing it.
Something along the line of
removeAdjDups' xs = foldl (\acc x -> removeAdjDups x acc) xs
Also is this approach the best way to implement the solution or is there a better way I should be thinking of?
Start in last-first order: first remove duplicates from the tail, then check if head of the input equals to head of the tail result (which, by this moment, won't have any duplicates, so the only possible pair is head of the input vs. head of the tail result):
main = mapM_ (print . squeeze) ["acvvca", "1456776541", "abbac", "aabaabckllm"]
squeeze :: Eq a => [a] -> [a]
squeeze (x:xs) = let ys = squeeze xs in case ys of
(y:ys') | x == y -> ys'
_ -> x:ys
squeeze _ = []
Outputs
""
""
"c"
"ckm"
I don't see how foldl could be used for this. (Generally, foldl pretty much combines the disadvantages of foldr and foldl'... those, or foldMap, are the folds you should normally be using, not foldl.)
What you seem to intend is: repeating the removeAdjDups, until no duplicates are found anymore. The repetition is a job for
iterate :: (a -> a) -> a -> [a]
like
Prelude> iterate removeAdjDups "1233213443"
["1233213443","122133","11","","","","","","","","","","","","","","","","","","","","","","","","","","",""...
This is an infinite list of ever reduced lists. Generally, it will not converge to the empty list; you'll want to add some termination condition. If you want to remove as many dups as necessary, that's the fixpoint; it can be found in a very similar way to how you implemented removeAdjDups: compare neighbor elements, just this time in the list of reductions.
bipll's suggestion to handle recursive duplicates is much better though, it avoids unnecessary comparisons and traversing the start of the list over and over.
List comprehensions are often overlooked. They are, of course syntactic sugar but some, like me are addicted. First off, strings are lists as they are. This functions could handle any list, too as well as singletons and empty lists. You can us map to process many lists in a list.
(\l -> [ x | (x,y) <- zip l $ (tail l) ++ " ", x /= y]) "abcddeeffa"
"abcdefa"
I don't see either how to use foldl. It's maybe because, if you want to fold something here, you have to use foldr.
main = mapM_ (print . squeeze) ["acvvca", "1456776541", "abbac", "aabaabckllm"]
-- I like the name in #bipll answer
squeeze = foldr (\ x xs -> if xs /= "" && x == head(xs) then tail(xs) else x:xs) ""
Let's analyze this. The idea is taken from #bipll answer: go from right to left. If f is the lambda function, then by definition of foldr:
squeeze "abbac" = f('a' f('b' f('b' f('a' f('c' "")))
By definition of f, f('c' "") = 'c':"" = "c" since xs == "". Next char from the right: f('a' "c") = 'a':"c" = "ac" since 'a' != head("c") = 'c'. f('b' "ac") = "bac" for the same reason. But f('b' "bac") = tail("bac") = "ac" because 'b' == head("bac"). And so forth...
Bonus: by replacing foldr with scanr, you can see the whole process:
Prelude> squeeze' = scanr (\ x xs -> if xs /= "" && x == head(xs) then tail(xs) else x:xs) ""
Prelude> zip "abbac" (squeeze' "abbac")
[('a',"c"),('b',"ac"),('b',"bac"),('a',"ac"),('c',"c")]

Creating a lists of lists with new element in each position

i'm new in the haskell world and i'd like to know how to insert a value in each position of a list in haskell, and return a lists of sublists containing the value in each position. For example:
insert' :: a -> [a] -> [[a]]
insert' a [] = [[a]]
insert' a list = ??
To get something like:
insert' 7 [1,2,3] = [[7,1,2,3],[1,7,2,3],[1,2,7,3],[1,2,3,7]]
insert' :: a -> [a] -> [[a]]
insert' y [] = [[y]]
insert' y xss#(x:xs) = (y : xss) : map (x :) (insert' y xs)
While the empty list case comes natural, let's take a look at insert' y xss#(x:xs). We essentially have two cases we need to cover:
y appears in front of x. Then we can just use y : xss.
y appears somewhere after x. We therefore just insert it in the rest of our list and make sure that x is the first element with map (x:).
Although #delta's answer is definitely more elegant, here a solution with difference lists. If we insert an element x on every location of list ys = [y1,y2,...,yn], the first time we will insert it as head, so that means we can construct x : ys.
. For the second element of the resulting list, we want to construct a list [y1,x,y2,...,yn]. We can do this like y1 : x : y2s. The next lists will all have a structure y1 : ....
The question is: how can we write a recursive structure that keeps track of the fact that we want to put elements in the head. We can use a function for that: we start with a function id. If we now call id (x:ys) then we will of course generate the list (x:ys).
We can however, based on the id function, construct a new function id2 = \z -> id (y1:z). This function will thus put y1 in the head of the list and then add the list with which we call id2 as tail. Next we can construct id3 = \z -> id2 (y2:z). This will put y1 and y2 as first elements followed by the tail z.
So we can put this into the following recursive format:
insert' :: a -> [a] -> [[a]]
insert' x = go id
where go d [] = [d [x]]
go d ys#(yh:yt) = (d (x : ys)) : go (d . (yh :)) yt
So we redirect insert' to go where the initial difference list is simply the id function. Each time we check if we have reached the end of the given list. If that is the case, we return the basecase: we call [x] (as tail) on the difference list, and thus construct a list where we append x as last element.
In case we have not yet reached the last element, we will first emit d (x : ys): we prepend x to the list and provide this as argument to the difference list d. d will prepend y1 : y2 : ... : yk up to the point where we insert x. Furthermore we call recursively go (d . (yh :)) yt on the tail of the list: we thus construct a new difference list, wehere we insert (yh :) as tail of the list. We thus produce a new function with one argument: the tail after the yh element.
This function produces the expected results:
*Main> insert' 4 []
[[4]]
*Main> insert' 4 [1,2,5]
[[4,1,2,5],[1,4,2,5],[1,2,4,5],[1,2,5,4]]
*Main> insert' 7 [1,2,3]
[[7,1,2,3],[1,7,2,3],[1,2,7,3],[1,2,3,7]]
You may also do as follows;
import Data.List
spread :: a -> [a] -> [[a]]
spread x xs = zipWith (++) (inits xs) ((x:) <$> tails xs)
*Main> spread 7 [1,2,3]
[[7,1,2,3],[1,7,2,3],[1,2,7,3],[1,2,3,7]]
*Main> spread 7 []
[[7]]
So this is about three stages.
(x:) <$> tails xs is all about applying the (x:) function to all elements of tails xs function. So tails [1,2,3] would return [[1,2,3],[2,3],[3],[]] and we are to apply an fmap which is designated by <$> in the inline form. This is going to be the third argument of the zipWith function.
(inits xs) which would return [[],[1],[1,2],[1,2,3]], is going to be the second argument to zipWith.
zipWith (++) is obviously will zip two list of lists by concatenating the list elements.
So we may also express the same functionality with applicative function functors as follows;
spread :: a -> [a] -> [[a]]
spread x = zipWith (++) <$> inits <*> fmap (x:) . tails
In this case we fmap the zipWith (++) function with type [[a]] -> [[a]] -> [[a]] over inits and then apply it over to fmap (x:) . tails.
It could get more pointfree but becomes more complicated to read through (at least for me). In my opinion this is as best as it gets.

Inverting List Elements in Haskell

I am trying to invert two-elements lists in xs. For example, invert [[1,2], [5,6,7], [10,20]] will return [[2,1], [5,6,7], [20,10]]. It doesn't invert [5,6,7] because it is a 3 element list.
So I have written this so far:
invert :: [[a]] -> [[a]]
invert [[]] = [[]]
which is just the type declaration and an empty list case. I am new to Haskell so any suggestions on how to implement this problem would be helpful.
Here's one way to do this:
First we define a function to invert one list (if it has two elements; otherwise we return the list unchanged):
invertOne :: [a] -> [a]
invertOne [x, y] = [y, x]
invertOne xs = xs
Next we apply this function to all elements of an input list:
invert :: [[a]] -> [[a]]
invert xs = map invertOne xs
(Because that's exactly what map does: it applies a function to all elements of a list and collects the results in another list.)
Your inert function just operations on each element individually, so you can express it as a map:
invert xs = map go xs
where go = ...
Here go just inverts a single list according to your rules, i.e.:
go [1,2] = [2,1]
go [4,5,6] = [4,5,6]
go [] = []
The definition of go is pretty straight-forward:
go [a,b] = [b,a]
go xs = xs -- go of anything else is just itself
I would do this:
solution ([a,b]:xs) = [b,a] : solution xs
solution (x:xs) = x : solution xs
solution [] = []
This explicitly handles 2-element lists, leaving everything else alone.
Yes, you could do this with map and an auxiliary function, but for a beginner, understanding the recursion behind it all may be valuable.
Note that your 'empty list case' is not empty. length [[]] is 1.
Examine the following solution:
invert :: [[a]] -> [[a]]
invert = fmap conditionallyInvert
where
conditionallyInvert xs
| lengthOfTwo xs = reverse xs
| otherwise = xs
lengthOfTwo (_:_:_) = True
lengthOfTwo _ = False

Haskell- looping every second element of list

I want to be able to loop every second element of a given list. I can do this recursively as so:
check validate (x:xs) = check (validate x) (tail xs)
But the problem is that I need a function that accepts a list as parameter, then returns a list consisting of only every second element in the list, starting with (and including) the first element of the list, and I do not think this is possible recursively.
Can someone show me how to this using list comprehension? This would probably be the best approach.
second (x:y:xs) = y : second xs;
second _ = []
List comprehension may not be useful.
You can also try mutual recursion
first [] = []
first (x:xs) = x:second xs
second [] = []
second (x:xs) = first xs
such as
> first [1..10]
[1,3,5,7,9]
> second [1..10]
[2,4,6,8,10]
One of the Haskellish approaches would be something with map, filter, and zip.
second xs = map fst $ filter (odd . snd) $ zip xs [1..]
If you really wanted to use list comprehension, you could use the parallel list comprehension extension.
{-# LANGUAGE ParallelListComp #-}
second xs = [ x | (x, n) <- [ (x, n) | x <- xs | n <- [1..] ], odd n ]
I think that the former is concise, though.