box*_*oxy 3 prolog coin-change
我是prolog的新手,试图解决这个经典的硬币找零问题。
用公式M> = 0和M = P + 5 * N + 10 * D来更改(M,P,N,D)这是我的方法
change(M,P,N,D) :-
M is P+5*N+10*D,
P is M - (5*N+10*10).
Run Code Online (Sandbox Code Playgroud)
几个测试用例
change(100,10,8,5).
True
change(X,10,8,5).
X = 100.
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试
change(100,P,8,5).
Run Code Online (Sandbox Code Playgroud)
它给了我“参数没有被充分实例化”,而不是P = 10。
编辑:通过在谓词之间(0,M,P),之间(0,M,N),之间(0,M,D),之间的谓词来修复我的代码,M是P + 5 * N + 10 * D。
使用clpfd!
:- use_module(library(clpfd)).
Run Code Online (Sandbox Code Playgroud)
我们需要表达的change/4
只是一个等式:
change(Money,Pennies,Nickels,Dimes) :-
Money #= Pennies + Nickels*5 + Dimes*10.
Run Code Online (Sandbox Code Playgroud)
让我们运行OP给出的基本查询!
?- change(100,10,8,5).
true.
Run Code Online (Sandbox Code Playgroud)
接下来,四个查询仅具有一个变量:
?-change (Money,10,8,5)。 金钱= 100。 ?-change(100,便士,8,5)。 便士= 10。 --change(100,10,镍,5)。 镍= 8。 ?-change(100,10,8,Dimes)。 角钱= 5。
当我们使用clpfd时,我们还可以问一些更通用的查询,例如带有三个变量的查询:
?- change(100,Pennies,Nickels,Dimes).
100 #= Pennies + 5*Nickels + 10*Dimes.
Run Code Online (Sandbox Code Playgroud)
请注意,这还没有(枚举)所有可能的组合...要这样做需要两个步骤:
使用以下命令声明“所有计数均为非负数” ins/2
:
?- [小便,镍,角钱] ins 0..sup, 零钱(100,小便,镍,角钱)。 100#=便士+ 5 *镍+ 10 *角钱, 硬币在0..100中, 0..20中的镍, 毛钱在0..10。
使用枚举谓词labeling/2
:
?-Zs = [小便,镍,角钱], Zs ins 0..sup, 零钱(100,小便,镍,角钱), labeling([],Zs)。 便士= 0,镍= 0,角钱= 10 ; 便士= 0,镍= 2,角钱= 9 ; 硬币= 0,镍= 4,角钱= 8 为简洁起见,省略了下一个115个答案的百分比 ; 便士= 90,镍= 2,角钱= 0 ; 便士= 95,镍= 1,角钱= 0 ; 硬币= 100,镍= 0,角钱= 0 ; 假。