Haskell function to swap every second element in a list - list
I'd like to know how to swap every second element of a list in Haskell.
Example output should look like this:
swap [1,2,3,4,5]
[2,1,4,3,5]
What I have so far is
swap :: [a] -> [a]
swap [] = []
swap (x:xs) = head xs : [x]
but this only swaps the first two elements and any attempt I make to make the function recursive causes errors when I try to load the file that contains the function. How to make it recursive?
You need to grab out 2 elements at a time:
swap [] = []
swap (x:y:rest) = y:x:(swap rest)
swap [x] = [x]
The last line is needed to allow odd-length lists -- it matches a list having length exactly 1, so it doesn't overlap either of the other 2 cases (length 0, and length 2 or more).
In addition to the other quite excellent replies, here is a solution that uses some very handy libraries. First, install split, which provides many very nice ways of splitting up a list. Our strategy for this problem will be to first split your list into chunks of size two, then swap each chunk, then concatenate the result back into a flat list. Here's how the key function works:
Prelude Data.List.Split> chunk 2 [1..11]
[[1,2],[3,4],[5,6],[7,8],[9,10],[11]]
To swap the elements of each chunk, we can simply call reverse. So the final result is:
Prelude Data.List.Split> let swap = concat . map reverse . chunk 2
Prelude Data.List.Split> swap [1..5]
[2,1,4,3,5]
#j_random_hacker's solution is better, however, if you want to see your implementation to completion, you could try this:
swap [] = []
swap (x:[]) = [x]
swap (x:xs) = head xs : x : (swap $ tail xs)
Notice however, the use of head and tail are unnecessary, and pattern matching can make things much cleaner here.
import Data.Function(on)
swap = map snd . concatMap reverse . groupBy ((==) `on` fst) . zip (cycle "aabb")
Don't take my solution too serious, I'm just trying to improve my Haskell-Foo...
Related
Calculate the differences of list elements using zipWith
I have to make a function called differences, where I calculate the difference of every pair with zipWith and put it in a list. For example differences [1..5] == [1, 1, 1, 1]. So [2-1, 3-2, 4-3, 5-4] == [1, 1, 1, 1]. I thought of making list of tuples, like this: [1..5] = [(1,2), (2,3), (3,4), (4,5)] Then use list comprehesion like this: [zipWith (-) a b | a <- y, b <- x] where x is the first element of the tuple and y is the second. The functions type is differences :: Num a => [a] -> [a].
You're nearly there - but zipWith itself returns a list, so you don't want to put that inside a list comprehension unless you want the result to be a list of lists (which you don't, here). zipWith (-) is absolutely the right idea here - it takes 2 lists and gives a new list given by taking the difference between corresponding elements of the given lists. Your output list, in your case, is intended to be 1 element shorter than the one input list, and you want to use zipWith (-) on 2 lists which consist of: all elements of the given list, other than the first all elements of the given list, other than the last Haskell already gives us convenient functions for these, namely tail and init. So the function you're looking for is: differences xs = zipWith (-) (tail xs) (init xs) Note that this isn't ideal, because both init and tail will crash your program with an ugly runtime error if xs is empty. It makes sense to output an empty list if you present an empty list to this function (although you could argue it doesn't, since you will get an empty list from a singleton list), so you can avoid a runtime crash by defining the function via pattern matching to explicitly cater for the empty list: differences [] = [] differences xs = zipWith (-) (tail xs) (init xs) While personally I think this is fine, and very explicit, you don't actually need to use both init and tail - zipWith works just fine if presented with lists of unequal length, when it will simply trim the larger one down to size. So differences xs = zipWith (-) (tail xs) xs is a viable, and slightly terser, alternative.
Building off Robin Zigmond's answer, the Applicative instance for functions works well here: (f <*> g) xs == f xs (g xs) so differences = zipWith subtract <*> tail (where subtract = flip (-).)
As 4castle suggests, using drop 1 instead of tail in Robin Zigmond's second, init-less solution means we can omit the [] case, as drop 1 [] = [] (unlike tail [], which leads to a runtime error): differences xs = zipWith (-) (drop 1 xs) xs To contrast with this solution with no explicit pattern deconstruction, I will mention a spelling using none of init, tail and drop: differences xs#(_:ys) = zipWith (-) ys xs
Generate all permutations of a list including diferent sizes and repeated elements
I wanted to create the function genAllSize ::[a] -> [[a]], that receives a list l and generates all the lists sorted by size that can be built with the elements of the list l; i.e. > genAllSize [2,4,8] [[],[2],[4],[8],[2,2],[4,2],[8,2],[2,4],[4,4],[8,4],[2,8],[4,8],[8,8],[2,2,2],[4,2,2],[8,2,2], ... How would you do it? I came up with a solution using permutations from Data.List but I do not want to use it.
Given an input list xs, select a prefix of that in a non deterministic way For each element in the prefix, replace it with any element of xs, in a non deterministic way Result: > xs = [2,4,8] > inits xs >>= mapM (const xs) [[],[2],[4],[8],[2,2],[2,4],[2,8],[4,2],[4,4],[4,8],[8,2],[8,4], [8,8],[2,2,2],[2,2,4],[2,2,8],[2,4,2],[2,4,4],[2,4,8],[2,8,2], [2,8,4],[2,8,8],[4,2,2],[4,2,4],[4,2,8],[4,4,2],[4,4,4],[4,4,8], [4,8,2],[4,8,4],[4,8,8],[8,2,2],[8,2,4],[8,2,8],[8,4,2],[8,4,4], [8,4,8],[8,8,2],[8,8,4],[8,8,8]]
The other answers seem sort of complicated. I'd do it this way: > [0..] >>= flip replicateM "abc" ["","a","b","c","aa","ab","ac","ba","bb","bc","ca","cb","cc","aaa","aab",...
Hmm I guess you a need a lazy infinite list of cycling subsequences. One naive way could be like Prelude> take 100 $ nub . subsequences . cycle $ [2,4,8] [[],[2],[4],[2,4],[8],[2,8],[4,8],[2,4,8],[2,2],[4,2],[2,4,2],[8,2],[2,8,2],[4,8,2],[2,4,8,2],[4,4],[2,4,4],[8,4],[2,8,4],[4,8,4],[2,4,8,4],[2,2,4],[4,2,4],[2,4,2,4],[8,2,4],[2,8,2,4],[4,8,2,4],[2,4,8,2,4],[8,8],[2,8,8],[4,8,8],[2,4,8,8],[2,2,8],[4,2,8],[2,4,2,8],[8,2,8],[2,8,2,8],[4,8,2,8],[2,4,8,2,8],[4,4,8],[2,4,4,8],[8,4,8],[2,8,4,8],[4,8,4,8],[2,4,8,4,8],[2,2,4,8],[4,2,4,8],[2,4,2,4,8],[8,2,4,8],[2,8,2,4,8],[4,8,2,4,8],[2,4,8,2,4,8],[2,2,2],[4,2,2],[2,4,2,2],[8,2,2],[2,8,2,2],[4,8,2,2],[2,4,8,2,2],[4,4,2],[2,4,4,2],[8,4,2],[2,8,4,2],[4,8,4,2],[2,4,8,4,2],[2,2,4,2],[4,2,4,2],[2,4,2,4,2],[8,2,4,2],[2,8,2,4,2],[4,8,2,4,2],[2,4,8,2,4,2]]
A simple and highly efficient option: genAllSize [] = [[]] genAllSize [a] = iterate (a:) [] genAllSize xs = [] : [x:q|q<-genAllSize xs,x<-xs] (Thanks to Will Ness for a small but very nice simplification.) This solution takes advantage of the fact that a valid solution list is either empty or an element of the argument list consed onto a shorter valid solution list. Unlike Daniel Wagner's solution, this one doesn't resort to counting. My tests suggest that it performs extremely well under typical conditions. Why do we need a special case for a one-element list? The general case performs extremely badly for that, because it maps over the same list over and over with no logarithmic slowdown. But what's the deal with that call to genAllSizes with the very same argument? Wouldn't it be better to save the result to increase sharing? genAllSize [] = [[]] genAllSize xs = p where p = [] : [x:q|q<-p,x<-xs] Indeed, on a theoretical machine with unlimited constant-time memory, this is optimal: walking the list takes worst-case O(1) time for each cons. In practice, it's only a good idea if a great many entries will be realized and retained. Otherwise, there's a problem: most of the list entries will be retained indefinitely, dramatically increasing memory residency and the amount of work the garbage collector needs to do. The non-bold sharing version above still offers amortized O(1) time per cons, but it needs very little memory (logarithmic rather than linear). Examples genAllSize "ab" = ["","a","b","aa","ba" ,"ab","bb","aaa","baa" ,"aba","bba","aab","bab" ,"abb","bbb","aaaa",...] genAllSize "abc" = ["","a","b","c","aa","ba" ,"ca","ab","bb","cb","ac" ,"bc","cc","aaa","baa" ,"caa","aba","bba","cba" ,"aca",...] An explicit option You can also use two accumulators: genAllSize [] = [[]] genAllSize [a] = iterate (a:) [] genAllSize (x:xs) = go ([], []) where go (curr, remain) = curr : go (step curr remain) step [] [] = ([x], [xs]) step (_:ls) ((r:rs):rss) = (r:ls, rs:rss) step (_:ls) ([] : rs) = (x : ls', xs : rs') where !(ls', rs') = step ls rs This version keeps track of the current "word" and also the remaining available "letters" in each position. The performance seems comparable in general, but a bit better with regard to memory residency. It's also much harder to understand!
This produces the elements in a different order within each length than your example, but it meets the definition of the text of your question. Changing the order is easy - you have to replace <*> with a slightly different operator of your own making. import Control.Applicative import Control.Monad rinvjoin :: Applicative both => both a -> both (both a) rinvjoin = fmap pure extendBranches options branches = (<|>) <$> options <*> branches singletonBranchExtensions = rinvjoin genAllSize [] = [] genAllSize xs = join <$> iterate (extendBranches extensions) $ initialBranches where extensions = singletonBranchExtensions xs initialBranches = pure empty
Manipulating Lists in Haskell using Higher-Order Functions and Lambda Calculus
I am trying to write a very simple function that takes a list (for example : [1,2,3,1,5]) and returns a list of elements that are directly after a specific element. What I have reached so far is: function element list = filter (\x -> element:x) list My desired output: function 1 [1,2,3,1,5] => [2,5]
Try this map snd $ filter ((== x) . fst) $ zip theList (tail theList) This won't work on an empty list, you will still need extra code to deal with that. How does this work? First, note that the values flow from right to left. The ($) operator allows this to happen. So, the first part evaluated is the zip function. zip theList (tail theList) For your example above, this would yield zip [1,2,3,1,5] [2,3,1,5] equaling [(1,2), (2, 3), (3, 1), (1,5)] which is the set of concurrent pairs in the list. Next, the filter is applied filter ((== x) . fst) $ .... In English, what this says is, filter out only the concurrent pairs whose first element equals x. The output is [(1,2), (1,5)] Now we have the list of concurrent pairs starting with 1. Finally, we apply the map map snd $ .... This just pulls out the second value of the pair. map snd [(1,2), (1,5)] = [2,5] which is the desired value. Note, my comment above about failing on the empty list. This is because tail crashes on the empty list tail [] --error There are ways to patch this behavior (see the safe package, for instance), but it is mostly bookkeeping at this point, so I left that for you to work out. Also note that since all of the functions we used are lazy, this approach would work for lists of infinite length as well.
You can do this quite easily with a simple list comprehension, e.g.: successors xs i = [y | (x,y) <- zip xs (drop 1 xs), x == i]
This will work to your specifications next x (i:y:ys) -- look at the first two items in the list | x == i = -- if the first item == x, y : next x (y:ys) -- take the second, and continue minus the first element |otherwise = -- not equal, next x (y:ys) -- so skip that element next _ [_] = [] -- if there's no second element, then stop next _ _ = [] -- if the list is empty, stop
How can I write a function in Haskell that takes a list of Ints and returns all the contiguous sublists of that list?
The function needs to take an ordered list of integer elements and return all the combinations of adjacent elements in the original list. e.g [1,2,3] would return [[1,2,3],[1],[1,2],[2],[2,3],[3]]. Note that [1,3] should not be included, as 1 and 3 are not adjacent in the original list.
Apart from the fact that inits and tails aren't found in Prelude, you can define your function as such: yourFunction :: [a] -> [[a]] yourFunction = filter (not . null) . concat . map inits . tails This is what it does, step by step: tails gives all versions of a list with zero or more starting elements removed: tails [1,2,3] == [[1,2,3],[2,3],[3],[]] map inits applies inits to every list given by tails, and does exactly the opposite: it gives all versions of a list with zero or more ending elements removed: inits [1,2,3] == [[],[1],[1,2],[1,2,3]] I hope you already know concat: it applies (++) where you see (:) in a list: concat [[1,2],[3],[],[4]] == [1,2,3,4]. You need this, because after map inits . tails, you end up with a list of lists of lists, while you want a list of lists. filter (not . null) removes the empty lists from the result. There will be more than one (unless you use the function on the empty list). You could also use concatMap inits instead of concat . map inits, which does exactly the same thing. It usually also performs better. Edit: you can define this with Prelude-only functions as such: yourFunction = concatMap inits . tails where inits = takeWhile (not . null) . iterate init tails = takeWhile (not . null) . iterate tail
So, if you need consecutive and non empty answers (as you've noticed in comment). At first, let's define a simple sublist function. sublist' [] = [[]] sublist' (x:xs) = sublist' xs ++ map (x:) (sublist' xs) It returns all sublists with empty and non-consecutive lists. So we need to filtering elements of that list. Something like sublists = (filter consecutive) . filter (/= []) . sublist' To check list for it's consecution we need to get pairs of neighbors (compactByN 2) and check them. compactByN :: Int -> [a] -> [[a]] compactByN _ [] = [[]] compactByN n list | length list == n = [list] compactByN n list#(x:xs)= take n list : compactByN n xs And finally consecutive :: [Int] -> Bool consecutive [_] = True consecutive x = all (\[x,y] -> (x + 1 == y)) $ compact_by_n 2 x And we have λ> sublists [1,2,3] [[3],[2],[2,3],[1],[1,2],[1,2,3]] Done. http://hpaste.org/53965
Unless, I'm mistaken, you're just asking for the superset of the numbers. The code is fairly self explanatory - our superset is recursively built by building the superset of the tail twice, once with our current head in it, and once without, and then combining them together and with a list containing our head. superset xs = []:(superset' xs) -- remember the empty list superset' (x:xs) = [x]:(map (x:) (superset' xs)) ++ superset' xs superset' [] = []
Comparing list length with arrows
Inspired by Comparing list length If I want to find the longest list in a list of lists, the simplest way is probably: longestList :: [[a]] -> [a] longestList = maximumBy (comparing length) A more efficient way would be to precompute the lengths: longest :: [[a]] -> [a] longest xss = snd $ maximumBy (comparing fst) [(length xs, xs) | xs <- xss] Now, I want to take it one step further. It may not be more efficient for normal cases, but can you solve this using arrows? My idea is basically, step through all of the lists simultaneously, and keep stepping until you've overstepped the length of every list except the longest. longest [[1],[1],[1..2^1000],[1],[1]] In the forgoing (very contrived) example, you would only have to take two steps through each list in order to determine that the list [1..2^1000] is the longest, without ever needing to determine the entire length of said list. Am I right that this can be done with arrows? If so, then how? If not, then why not, and how could this approach be implemented?
OK, as I was writing the question, it dawned on me a simple way to implement this (without arrows, boo!) longest [] = error "it's ambiguous" longest [xs] = xs longest xss = longest . filter (not . null) . map (drop 1) $ xss Except this has a problem...it drops the first part of the list and doesn't recover it! > take 3 $ longest [[1],[1],[1..2^1000],[1]] [2,3,4] Needs more bookkeeping :P longest xs = longest' $ map (\x -> (x,x)) xs longest' [] = error "it's ambiguous" longest' [xs] = fst xs longest' xss = longest . filter (not . null . snd) . map (sndMap (drop 1)) $ xss sndMap f (x,y) = (x, f y) Now it works. > take 3 $ longest [[1],[1],[1..2^1000],[1]] [1,2,3] But no arrows. :( If it can be done with arrows, then hopefully this answer can give you someplace to start.
Thinking about this some more, there is a far simpler solution which gives the same performance characteristics. We can just use maximumBy with a lazy length comparison function: compareLength [] [] = EQ compareLength _ [] = GT compareLength [] _ = LT compareLength (_:xs) (_:ys) = compareLength xs ys longest = maximumBy compareLength
Here's the most straightforward implementation I could think of. No arrows involved, though. I keep a list of pairs where the first element is the original list, and the second is the remaining tail. If we only have one list left, we're done. Otherwise we try taking the tail of all the remaining lists, filtering out those who are empty. If some still remain, keep going. Otherwise, they are all the same length and we arbitrarily pick the first one. longest [] = error "longest: empty list" longest xss = go [(xs, xs) | xs <- xss] where go [(xs, _)] = xs go xss | null xss' = fst . head $ xss | otherwise = go xss' where xss' = [(xs, ys) | (xs, (_:ys)) <- xss]