Рекурсивно сортировать несмежные списки в список смежных списков - PullRequest
6 голосов
/ 18 февраля 2011

В последнее время я пытался немного изучить функциональное программирование (с помощью Haskell & Erlang), и меня всегда поражали краткие решения, которые люди могут придумать, когда они могут рекурсивно мыслить и знать инструменты.

Я хочу, чтобы функция преобразовывала список отсортированных, уникальных, несмежных целых чисел в список смежных списков, т.е.:

[1,2,3,6,7,8,10,11]

до:

[[1,2,3], [6,7,8], [10,11]

Это было лучшее, что я мог придумать в Haskell (две функции) ::

make_ranges :: [[Int]] -> [Int] -> [[Int]]
make_ranges ranges [] = ranges
make_ranges [] (x:xs)
    | null xs = [[x]]
    | otherwise = make_ranges [[x]] xs
make_ranges ranges (x:xs)
    | (last (last ranges)) + 1 == x =
        make_ranges ((init ranges) ++ [(last ranges ++ [x])]) xs
    | otherwise = make_ranges (ranges ++ [[x]]) xs

rangify :: [Int] -> [[Int]]
rangify lst = make_ranges [] lst    

Это может быть немного субъективно, но мне было бы интересно увидеть лучшее, более изящное, решение этого на Erlang или Haskell (также на других функциональных языках, но я не могу этого понять). В противном случае, пункты для простого исправления стиль моего дерьмового новичка в Haskell!

Ответы [ 12 ]

2 голосов
/ 18 февраля 2011

Это мой v0.1, и я, вероятно, могу сделать его лучше:

makeCont :: [Int] -> [[Int]]
makeCont [] = []
makeCont [a] = [[a]]
makeCont (a:b:xs) = if b - a == 1
                        then (a : head next) : tail next
                        else [a] : next
                    where
                        next :: [[Int]]
                        next = makeCont (b:xs)

И я постараюсь сделать его лучше.Я думаю, что редактирование наступает.

1 голос
/ 18 февраля 2011

Вот попытка хукелла noob

ranges ls = let (a, r) = foldl (\(r, a@(h:t)) e -> if h + 1 == e then (r, e:a) else (a:r, [e])) ([], [head ls]) (tail ls)
            in           reverse . map reverse $ r : a
...