2009-12-13 33 views
1

我想對每一個結果進行求和運算:Prolog的語法 - 使用功能導致

combination(0,_,[]). 
combination(K,L,[X|Xs]) :- 
    K > 0, 
    el(X,L,R), 
    K1 is K-1, 
    combination(K1,R,Xs). 

el(X,[X|L],L). 
el(X,[_|L],R) :- el(X,L,R). 

例如,用戶將進入is_sum_equal_10([1,2,3,4,5,6 ,7]),結果將是真實的,如果任何排列的總和等於10.

我很努力把它放在一起,有人可以幫我定義is_sum_equal_10規則,每個規則使用組合規則排列?

回答

2

好吧,寫起來真的很容易,你只需要一個規則來說明一個特定的組合是否爲10,然後另一個額外的一個通過不同大小的組合列表來計數(這是因爲你用K寫的組合方式,你在檢查規則時需要減少)。

1 ?- [user]. 
|: combination(0,_,[]). 
|: combination(K,L,[X|Xs]) :- K > 0, 
|: el(X,L,R), K1 is K-1, combination(K1,R,Xs). 
|: el(X,[X|L],L). 
|: el(X,[_|L],R) :- el(X,L,R). 
|: 
|: totals_10([],10). 
|: totals_10([X|Xs],T) :- N is T+X, totals_10(Xs,N). 
|: 
|: is_comb_sum_equal_10(Numbers,_,R) :- combination(R,Numbers,C), totals_10(C,0). 
|: is_comb_sum_equal_10(Numbers,N,R) :- Rnext is R+1, Rnext =< N, 
|: is_comb_sum_equal_10(Numbers,N,Rnext). 
|: 
|: is_sum_equal_10(Numbers) :- length(Numbers,N), is_comb_sum_equal_10(Numbers,N,0). 
|: 
% user://1 compiled 0.13 sec, 1,824 bytes 
true. 

2 ?- is_sum_equal_10([2,3,5]). 
true . 

3 ?- is_sum_equal_10([2,235,124,3,3347,5,2373]). 
true . 

4 ?- is_sum_equal_10([2,235,124,3,3347,6,2373]). 
false. 

5 ?- is_sum_equal_10([1,1,1,1,1,-1,1,1,1,1,12]). 
false. 

6 ?- is_sum_equal_10([1,1,1,1,1,-1,1,1,1,1,11]). 
true ; 
false. 

既然你不關心實際的列表或有多大它是在is_sum_equal_10的事情,你可以總結的組合,你走,甚至更好,檢查總和作爲一項規則正確爲基礎案例。我認爲如果你從基數中減去所需的總數來得到0,而不是在最後加上和檢查你想要的值,那麼這有點兒整潔。這給你一個非常簡單的單一規則集來尋找一定的總和。

7 ?- [user]. 
|: is_subset_sum(0,[]). 
|: is_subset_sum(N,[_|Xs]) :- is_subset_sum(N,Xs). 
|: is_subset_sum(N,[X|Xs]) :- R is N-X, is_subset_sum(R,Xs). 
|: 
% user://2 compiled 0.03 sec, 540 bytes 
true. 

8 ?- is_subset_sum(10,[3,5,6]). 
false. 

9 ?- is_subset_sum(10,[123,4,1,77,3,2,34]). 
true . 

10 ?- is_subset_sum(11,[0,2,4,6,8,10,12,14,16,18,20,22]). 
false. 

這種方法當然更容易理解,並且效率更高。

+0

謝謝,KernelJ,爲這樣一個詳細的答案。還有一件事 - 爲了簡化任務 - 我想將置換大小設置爲5的預定義值。因此,每次只檢查給定列表中5個整數的置換集合是否總和最多10個。 我試圖將R值設置爲5,但我一直對任何計算嘗試都得到錯誤的答案。給定輸入列表的未知長度,我需要更改哪個值以檢查每次嘗試設置的固定排列大小? 謝謝你的幫助! Amy – Amy 2009-12-13 15:12:10

+0

我覺得很明顯,如何根據已經存在的代碼制定新的規則,您只需在規則中使用組合和totals_10即可。這是一條線!自己寫一下;如果您仍然遇到麻煩,請發佈您嘗試的類型,然後或許我可以找出您不明白的部分。 – KernelJ 2009-12-13 16:04:43

+0

我試過的是增加一行: is_comb_sum_equal_10(Numbers,_,5): - combination(5,Numbers,C),totals_10(C,0)。 現在我只是用新行代替了最初的行(有5行而不是R行)。工作!:) 除了它,如果我想添加另一個條件,我可以寫一個新函數first_2_last ,然後將條件添加到同一行,如下所示: is_comb_sum_equal_10(Numbers,_,5): - combination(5,Numbers,C),totals_10(C,0),first_to_last(C)。 它會確保新條件在整個列表中的5個整數的當前組合上運行嗎? – Amy 2009-12-13 16:38:00