オフラインどう書く第19回参考問題

問題はこちら->http://nabetani.sakura.ne.jp/hena/ord19sanwa/

最初 コード量を減らすためできるだけ一括処理するプログラムを書いたのですが遅いので、
次の数について考える前の三和数の候補となるリストの要素の数ごとに場合分けして、
新しいリストを作るプログラムを書いてみました。
col/3で場合分けに従って、前のリストの要素のまま、あるいは空きがあれば新しい要素を加えて、
和がNになる組み合わせを求め、要素から0を削除します。
リストの要素数が0の場合
　まず最初の入力に対しては、計算数を減らすために、ZがN/3以下、YがZ以上N/2以下、
　Xが残りとして条件に合う値を求めます。
リストの要素数が1の場合、
　それを0~2個使うそれぞれに対して、三番目の要素（値を残りの1/2以下に制限）を
　2~0個までつかい、条件を満たす二番目の要素を求めます。
リストの要素数が2の場合、
　二つの要素合わせて0~2個使った残りをそれぞれ三番目の要素3~1個までで分割し、
　整数になるものを求めます。
リストの要素数が3の場合、
　三要素合わせて0~3個使う組み合わせすべてを調べます。
sel/3のfindallで題意に沿う新しいリストをすべて集め、其々ソートして重複する数字を1つにし、
さらに組み合わせ（リスト）を集めたリストをソートして重複する組み合わせを一つにし、
foldlの次の入力値に渡します。

```Prolog
%SWI-Prolog version 7.4.2,7.6.4 
%:-initialization(start).    %ideone
%start.
col(N,[],R):-
     N1 is N div 2,N2 is N div 3,between(0,N2,Z),between(Z,N1,Y),
     X is N-Y-Z, delete([X,Y,Z],0,R).    
col(N,[X],R):-
     between(0,2,K1),N1 is N-X*K1,(N1=:=0->R=[X];
     (N1>0,N2 is N1 div 2,K2 is 2-K1,between(1,N2,Z),
     between(0,K2,K3),Y is N1-Z*K3,delete([X,Y,Z],0,R))).
col(N,[X,Y],R):-
     between(0,2,K1),K2 is 2-K1,between(0,K2,K3),N1 is N-K1*X-K3*Y,N1>=0,
     (N1=:=0->R=[X,Y];(K4 is 3-K1-K3,between(1,K4,K5),divmod(N1,K5,D,M),M=:=0,R=[X,Y,D])).
col(N,[X,Y,Z],[X,Y,Z]):-
     between(0,3,H),M1 is 3-H,between(0,M1,I),M2 is 3-H-I,between(0,M2,J),N=:=X*H+Y*I+Z*J.

sel(N,L,R):-sel(N,L,[],R).
sel(_,[],R,R).
sel(N,[H|T],R2,R):-
     findall(L,col(N,H,L),L1),maplist(sort,L1,L2),
     append(R2,L2,L3),sort(L3,R1),sel(N,T,R1,R).

solve([H|T],R):-foldl(sel,[H|T],[[]],R1),sort(R1,R),!.

start:-
     str(S),split_string(S,"\s\n","\s",L),maplist(split,L,L1),pre(L1).
     
split(S,L):-atomics_to_string(L,",",S).

        %split_string(S,"\n","",L) demo yoi
pre([]).
pre([_,B,C|T]):-maplist(atom_number,B,B1),solve(B1,R),disp(R,C),pre(T).

disp(L,D):-
     length(L,N),(N=:=0->R=[none];(N>1->R=[many];([L1]=L,maplist(atom_number,R,L1)))),
     atomics_to_string(R,",",S),(R==D->S1="pass  ";S1="fail  "),write(S1),writeln(S).

str("0  3,11,12,102,111,120     1,10,100
1       10,20,30,35,70  many
2       1,5,20,80       none
3       1,2,3,4,5,6,7,8,9,10,11,12,13,14        many
4       1,2,3,4,5,6,7,8,9,10,11,12,13,14,15     1,4,5
5       1,2,3,4,5,6,7,8,9,10,11,12,13,14,17     none
6       1,2,3,4,5,6,7,8,9,10,11,12,13,14,18     1,4,6
7       5,6,7,8,9,10,11,12,13,14,15,16  2,5,6
8       9,10,11,12,13,14,15,16,17,18,19         4,5,7
9       11,36,37,45,55,70,71    1,10,35
10      92,93,94,95,96,97,98,99         30,32,33
11      95,96,97,98,99,100      many
12      27,30,34,37,43,44,46,51,57      10,17,23
13      6,10,13,17,65,73,76,80  none
14      12,19,21,29,85  none
15      1,2,8,10,14,23,58,62,64         none
16      4,22,25,31,44,50,58,69,71,72,73,77      none
17      8,16,26,27,42,53,65,69,81,83,88,99      none
18      9,10,23,24,28,33,38,39,58,68,84         none
19      11,16,24,26,88  none
20      24,33,47,56,63,66,75,78,89,93   none
21      7,26,72,77      many
22      69,88,95,97     many
23      9,14,48,89      many
24      69,76,77,83     many
25      11,14,24        many
26      8,25,75,93      many
27      11,55,93,98,99  many
28      71,83,87        many
29      22,76,77,92     7,15,62
30      33,61,66,83,95  17,33,61
31      6,16,49,55,72   6,16,33
32      62,85,97,98     12,25,73
33      54,60,67,70,72  20,25,27
34      54,61,68,84,87  27,30,34
35      65,67,69,75,79,89,99    21,23,33
36      69,72,80,81,89  23,24,33
37      1,2,3   many").
```
もっとすっきりした解法があっても良さそうですが見当がつきません。