In Erlang, it can be pretty clear and simple:
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)].
Edit : just for the sake of curiosity, I compared my version and Lukas version and mine seems to be about 10% faster in either the native or the bytecode version when testing, established by the fact that I created lists:usort([random:uniform(1000000)||_<-lists:seq(1,1000000)]) on the R14B01 64b version on my laptop. (The test kit is 669462 and is divided into 232451 subscriptions).
Edit2 . Other test data lists:usort([random:uniform(1000000)||_<-lists:seq(1,10000000)]) , length 999963 and 38 sections make a larger spread in the native code. Finishing work in a mine is less than half the time. The bytecode version is about 20% faster.
Edit3 : some micro-optimizations that provide extra performance, but lead to uglier and less supported code:
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])].
Hynek -Pichi- Vychodil
source share