given
xs = [1,2,3,4,6,7,9,10,11]
I am aiming to return
[[1,2,3,4],[6,7],[9,10,11]]
I thought I could do:
groupBy (\x y -> succ x == y) xs
but this returns:
[[1,2],[3,4],[6,7],[9,10],[11]]
a little bit of searching returned the following from the Haskell Data.List suggestion page.
groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
groupBy rel [] = []
groupBy rel (x:xs) = (x:ys) : groupBy rel zs
where (ys,zs) = groupByAux x xs
groupByAux x0 (x:xs) | rel x0 x = (x:ys, zs)
where (ys,zs) = groupByAux x xs
groupByAux y xs = ([], xs)
One of the examples they give is exacly what I am looking for:
groupBy (\a b -> a+1 == b) [1,2,3,4,6]
[[1,2,3,4],[6]]
So My question... Is there another approach to this, as opposed to re-defining groupBy
as it seems a little dramatic?
EDIT...
I have decided to implement it as follows:
pattern :: (Enum a, Eq a) => (a -> a) -> [a] -> [[a]]
pattern f = foldr g []
where g a [] = [[a]]
g a xs | f a == head (head xs) = (a : head xs): tail xs
| otherwise = [a]:xs
which allows for such things:
*Main Map> pattern succ "thisabcdeisxyz"
["t","hi","s","abcde","i","s","xyz"]
*Main Map> pattern (+ 3) [3,6,9,12,1,2,3,2,5,8,23,24,25]
[[3,6,9,12],[1],[2],[3],[2,5,8],[23],[24],[25]]
or to function exactly like group
-- not that there is any reason:
*Main Map> let xs = [1,1,1,2,3,4,5,6,6,6,5]
*Main Map> group xs == pattern id xs
True
To calculate the number of subarrays that include the element at the ith index, we simply subtract the number of subarrays not including the element at the ith index from the total number of ways.
A contiguous subarray is simply a subarray of an array with a condition that the elements of the subarray should be in exact sequence as the sequence of the elements in the array.
If all elements are distinct, then a subarray has contiguous elements if and only if the difference between maximum and minimum elements in subarray is equal to the difference between last and first indexes of subarray. So the idea is to keep track of minimum and maximum element in every subarray.
The number of all possible subarrays of an array of size N is N * (N + 1)/2.
There are many ways to do that. One way can be using foldr
f = foldr g []
where g a [] = [[a]]
g a xs@(x:xs') | a+1 == head x = (a : x): xs'
| otherwise = [a]:xs
Now trying this in action
*Main> f [1,2,3,4,6,7,9,10,11]
[[1,2,3,4],[6,7],[9,10,11]]
If xs
is strictly increasing then
myGrouping = map (map snd) . groupBy (\(u, v) (x, y) -> u - v == x - y) . zip [0..]
solve your problem.
Prelude> myGrouping [1,2,3,4,6,7,9,10,11]
[[1,2,3,4],[6,7],[9,10,11]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With