Reputation: 23955
I wrote a function that seems to work fine. (On second thought, it missed connecting the first two groups...I'll have to think more about that.)
import Data.List (groupBy)
makeGroups xs =
map concat $ groupBy (\a b -> head b == last a + 1) (groupBy mGroups0 xs)
where mGroups0 = \a b -> a == length xs && elem b [1,2]
|| b /= length xs && b == a + 1
OUTPUT:
*Main> makeGroups [3,4,5,6,7,8,1,9,10,2]
[[3,4,5,6],[7,8],[1],[9,10,2]]
(Thank you all for the answer about the tabs...now I'm asking for just general coding genius)
Might there be more efficient/convenient ways to group sorted ascending integer sequences in a list (keeping the original order)?
The only extra stipulation is that:
the possible groups [length xs] [1] [2] [1,2] [length xs,1] [length xs,2]
must be separated, but [length xs, 1, 2] should join any larger sequence.
Upvotes: 1
Views: 195
Reputation: 23955
something like this? (Thanks to Daniel Fischer's suggestions)
makeGroups xs = foldr comb [[last xs]] (init xs) where
comb a b = if a == head (head b) - 1
then (a:head b) : tail b
else [a] : b
*Main> makeGroups [3,4,5,6,7,8,1,9,10,2]
[[3,4,5,6,7,8],[1],[9,10],[2]]
And here's a stab at the ugly:
makeGroups xs = foldr comb [[last xs]] (init xs)
where n = length xs
ngroup = [1,2,n]
comb a b = let (x:xs) = head b in
if a == n && isPrefixOf [1,2] (x:xs)
then if not (null $ tail b) && head (head $ tail b) == 3
then ((n:head b) ++ (head $ tail b)) : drop 1 (tail b)
else (n:head b) : tail b
else if a == n && isPrefixOf [2,1] (x:xs)
then if null (drop 1 xs)
then [n,2,1] : tail b
else [n,2,1] : drop 1 xs : tail b
else if elem a ngroup
then if elem x ngroup
then if null xs
then [a,x] : tail b
else [a,x] : xs : tail b
else [a] : b
else if a /= n && a == x - 1
then if x /= n
|| isPrefixOf [n,1,2] (x:xs)
then (a:x:xs) : tail b
else [a] : b
else [a] : b
Upvotes: 1