您好我想编写一个名为perfect_part的函数,它将整数列表作为输入,如果可能,返回两个子列表,其总和恰好是原始列表中所有整数的总值的一半。 例如,
?- perfect_part([6, 3, 2, 1], L, R).
L = [6],
R = [3, 2, 1] ;
false.
?- perfect_part([1, 2, 3, 4, 0], L, R).
L = [1, 4],
R = [2, 3, 0] ;
L = [2, 3],
R = [1, 4, 0] ;
这是我的尝试:
listsum([], 0).
listsum([H|T], Total):-
listsum(T, Sum1),
Total is H + Sum1.
subset([],L).
subset([X|T],L):- member(X,L),subset(T,L).
perfect_part([], 0, 0).
perfect_part(Nums, Left, Right):-
listsum(Nums, S),
H is S / 2,
subset(Left, Nums),
subset(Right, Nums),
listsum(Left, H),
listsum(Right, H).
但如果我运行它,我收到错误消息:
错误:是/ 2:参数没有充分实例化
我该如何解决?我是否正确地解决了这个问题?
答案 0 :(得分:1)
缺少谓词子集/ 2,它是回答问题的重要部分。具体来说,如果子列表是连续的,您可以像
一样轻松解决perfect_part(X,L,R) :- append(L,R,X), listsum(L,S), listsum(R,S).
然后我会寻找更适合append / 3的替代品,比如
partition([],[],[]).
partition([H|T],[H|L],R) :- partition(T,L,R).
partition([H|T],L,[H|R]) :- partition(T,L,R).
导致
perfect_part(X,L,R) :- partition(X,L,R), listsum(L,S), listsum(R,S).
编辑现在,从子集/ 2中可以看出错误原因:在基本情况下,L是未绑定的。
应为subset([],[]).
,但不会终止。我想知道你是怎么得到错误的......
more edit 为避免重复解决方案,我建议用
打破对称性perfect_part(X,L,R) :- partition(X,L,R), L @=< R, listsum(L,S), listsum(R,S).