拆分数字,以所有可能的方式分组

时间:2015-07-05 20:22:28

标签: split prolog

我有一个数字,比方说123,我想生成一组所有可能的方法来分割它:

[[1, 23], [12, 3], [1, 2, 3]].

我想过要创建[1,2,3]的幂集:

?- findall(Powerset, powerset([1,2,3], Powerset), Z).
Z = [[1], [1, 2], [1, 2, 3], [2], [2, 3], [3]].

然后将这些集合在一起并用append/3检查它们的串联是否是初始集合[1,2,3],即

[[1], [2, 3]] -> [1, 23]
[[1, 2], [3]] -> [12, 3]
[[1], [2], [3]] -> [1, 2, 3]

您是否考虑过另一种更简单(更优雅)的解决方案?

我使用gnu Prolog powerset modification

中的这个谓词
powerset(L, [H|T]):-
  append([H|T], _, L).
powerset([_|L], P):-
  powerset(L, P).

2 个答案:

答案 0 :(得分:2)

此处无需使用findall/3 ---使用

int_split(X) -->
   int_split__aux(X,10,[]).

int_split__aux(X,P,Ds) -->
   (  { X =:= 0 }
   -> [Ds]
   ;  { X < P }
   -> [[X|Ds]]
   ;  { X0 is X mod P,
        X1 is X div P },
      int_split__aux(X1,10,[X0|Ds]),
      { P1 is P*10 },
      int_split__aux(X,P1,Ds)
   ).

样品使用:

?- phrase(int_split(123),Zss).
Zss = [[1,2,3], [12,3], [1,23], [123]].

?- phrase(int_split(1234),Zss).
Zss = [[1,2,3,4], [12,3,4], [1,23,4], [123,4], [1,2,34], [12,34], [1,234], [1234]].

答案 1 :(得分:2)

而不是powerset,我们可以有一个更集中的谓词

parts(C, [C]).
parts(L, Ps) :-
    append(H, T, L), H \= [], T \= [],
    parts(T, Ts),
    append([H], Ts, Ps).

现在

?- number_codes(123,Cs),parts(Cs,Ps),maplist(number_codes,Ns,Ps).
Cs = [49, 50, 51],
Ps = [[49, 50, 51]],
Ns = [123] ;
...etc...

所以我们可以用findall

收集有趣的N.
?- findall(Ns,(number_codes(123,Cs),parts(Cs,Ps),maplist(number_codes,Ns,Ps)),Rs).
Rs = [[123], [1, 23], [1, 2, 3], [12, 3]].