Это может быть довольно ясно и просто в Эрланге:
partition([]) -> [];
partition([A|T]) -> partition(T, [A]).
partition([A|T], [B|_]=R) when A =:= B+1 -> partition(T, [A|R]);
partition(L, P) -> [lists:reverse(P)|partition(L)].
Редактировать : Просто для любопытства я сравнил свои и Лукас х версия и моя, кажется, примерно на 10% быстрее либо в нативном, либо в версии с байт-кодом при тестировании, что я сгенерировал lists:usort([random:uniform(1000000)||_<-lists:seq(1,1000000)])
на версии R14B01 64b на моем ноутбуке.(Набор для тестирования имеет длину 669462 и был разделен на 232451 подсписков.)
Edit2 : Другие данные теста lists:usort([random:uniform(1000000)||_<-lists:seq(1,10000000)])
, длина 999963 и 38 разделов, значительно отличаются от собственного кода.Моя версия заканчивается менее чем за половину времени.Версия байт-кода работает примерно на 20% быстрее.
Edit3 : некоторые микрооптимизации, которые обеспечивают дополнительную производительность, но приводят к более уродливому и менее обслуживаемому коду:
part4([]) -> [];
part4([A|T]) -> part4(T, A, []).
part4([A|T], B, R) when A =:= B+1 -> part4(T, A, [B|R]);
part4([A|T], B, []) -> [[B]|part4(T, A, [])];
part4([A|T], B, R) -> [lists:reverse(R, [B])|part4(T, A, [])];
part4([], B, R) -> [lists:reverse(R,[B])].