2013-03-14 3 views
1

Я написал функцию, которая, кажется, работает нормально. (На второй мысли, он пропустил, соединяющий две первые группы ... Я буду думать об этом больше.)группировка отсортированных по возрастанию целых последовательностей - изменен

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 


ВЫВОД:

*Main> makeGroups [3,4,5,6,7,8,1,9,10,2] 
[[3,4,5,6],[7,8],[1],[9,10,2]] 

(Спасибо всем за ответ о вкладках ... теперь я прошу только общий гений кодирования)

Возможно ли быть более эффективным/удобным способом группировки отсортированных восходящих целых последовательностей в списке (сохраняя исходный порядок)?

Единственное дополнительное условие заключается в следующем:

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. 
+0

Любой причина, почему вы пишете локальные функции с синтаксисом лямбды? Это немного раздражает, если не сказать больше. – Ingo

+0

@Ingo Это не важно для меня. Я просто подумал, что попробую на этот раз проверить, работает ли это вообще. –

+0

Вторая догадка: есть ли у вас какие-либо символы табуляции в исходном коде? – Ingo

ответ

1

что-то вроде этого? (Благодаря предложениям Даниэля Фишера)

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]] 


А вот удар в безобразном:

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 
+0

Это начало, но правила для 'length xs' усложняют ситуацию. –

+0

@ DanielFischer удар в уродливый. работая над makeover –

+0

Э-э, это действительно уродливо. Одно дело в том, что вы должны связывать 'n = length xs' снаружи' comb', нет смысла рисковать его пересчитать. Другое дело, что он не достаточно ленив (это также относится к первому удару), если у вас есть 'if not (null b)' наверху, вы вынуждаете весь список перемещаться, прежде чем что-либо будет сделано. Позвольте мне посмотреть, смогу ли я сделать его короче и ленивее. –

Смежные вопросы