所以这是一个货币系统,它用8种不同的硬币值来计算最少的硬币数量。例如:1美分、2美分、4美分、33美分等等。其中一枚硬币的价值必须是"5"。因此,这个程序试图确定其他7种价值的硬币必须具有哪些单独的价值,以及每种价值的硬币总数在1到99美分之间。
所以我的问题是,有没有一种方法可以编写一段代码,而不必手动在程序中插入一个'5'(例如:Values =[_, _, _, _, 5, _, _, _]或Values = [_, 5, _, _, _, _])?所以这里应该有不止一个解决方案…
代码:
questionSix(Values, Coins) :-
init_vars(Values, Coins),
coin_cons(Values, Coins, Pockets),
clever_cons(Values, Coins),
Min #= sum(Coins),
minimize((labeling(Values), labeling(Coins), check(Pockets)), Min).
init_vars(Values, Coins) :-
length(Values, 8),
Values = [_, _, _, 5, _, _, _, _],
Values :: 1..99,
increasing(Values),
length(Coins, 8),
Coins :: 0..99.
increasing(List) :-
( fromto(List, [This, Next | Rest], [Next | Rest], [_])
do
This #< Next
).
clever_cons(Values, Coins) :-
( fromto(Values, [V1 | NV], NV, []),
fromto(Coins, [N1 | NN], NN, [])
do
( NV = [V2 | _]
-> N1*V1 #< V2;
N1*V1 #< 100
)
).
任何帮助都是感激的。谢谢你!
您可以使用ic_global
库中的occurrences
(http://eclipseclp.org/doc/bips/lib/ic_global/occurrences-3.html):
occurrences(5, Values, 1)
另一个更长的方法,但没有ic_global
,是建立约束的析取,第一个值是5,或者第二个值是5,等等(我还没有测试过这个代码):
( foreach(Vi, Values), fromto(0, Eprev, Ecurr, Expr) do
Ecurr = Eprev or (Vi #= 5) ),
1 #= eval(Expr)