より効率的なアルゴリズムを求めると、どれを比較すればよいかわかりません。しかし、これは単純な方法で書かれたアルゴリズムの 1 つです (Erlang):
-module(partitions).
-export([partitions/1]).
partitions(N) -> partitions(N, N).
partitions(N, Max) when N > 0 ->
[[X | P]
|| X <- lists:seq(min(N, Max), 1, -1),
P <- partitions(N - X, X)];
partitions(0, _) -> [[]];
partitions(_, _) -> [].
時間的には指数関数的 ( Python での Can Berk Güder のソリューションと同じ) であり、スタック空間では線形です。しかし、同じトリックであるメモ化を使用すると、メモリを節約し、指数を減らすことで大幅な改善を実現できます。(N=50 で 10 倍高速)
mp(N) ->
lists:foreach(fun (X) -> put(X, undefined) end,
lists:seq(1, N)), % clean up process dictionary for sure
mp(N, N).
mp(N, Max) when N > 0 ->
case get(N) of
undefined -> R = mp(N, 1, Max, []), put(N, R), R;
[[Max | _] | _] = L -> L;
[[X | _] | _] = L ->
R = mp(N, X + 1, Max, L), put(N, R), R
end;
mp(0, _) -> [[]];
mp(_, _) -> [].
mp(_, X, Max, R) when X > Max -> R;
mp(N, X, Max, R) ->
mp(N, X + 1, Max, prepend(X, mp(N - X, X), R)).
prepend(_, [], R) -> R;
prepend(X, [H | T], R) -> prepend(X, T, [[X | H] | R]).
とにかく、言語と目的をベンチマークする必要があります。