根据现金金额和货币列表生成变更
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了根据现金金额和货币列表生成变更相关的知识,希望对你有一定的参考价值。
我正在尝试在Prolog中编写一个程序,它做了两件事:
- 采用两个参数,一个整数和一个整数列表
- 如果第一个参数的更改可以来自第二个元素的某些组合,则表示满意
我想出了一个解决这个问题的方法,它允许变更规则统一到硬币事实,如下:
coin(quarter, 25).
coin(dime,10).
coin(nickel,5).
coin(penny,1).
change(0, []).
change(A, [(C, Num)|L]) :-
coin(C, V),
A >= V,
Num is floor(A / V),
B is A mod V,
change(B, L).
此外,如果您将更改(27,L)之类的内容传递给解释器,它会生成可用于进行更改的四分之一,硬币,镍币和便士的所有可能组合,如下所示:
?- change(27,L).
L = [(quarter, 1), (penny, 2)] ;
L = [(dime, 2), (nickel, 1), (penny, 2)] ;
L = [(dime, 2), (penny, 7)] ;
L = [(nickel, 5), (penny, 2)] ;
L = [(penny, 27)] ;
false.
然而,我遇到了麻烦,如何通过简单地将[25,10,5,1]这样的货币列表传递给变更来解决这个问题,使得看起来像变化(27,[25,10,5, 1],L)。这是可能的,如果是这样,怎么办?
答案
所以你真的非常接近。这基本上是我留下的评论,扩展了。让我们为造币类型添加另一个论点。
change(0, _, []).
change(A, Coinage, [(C, Num)|L]) :-
member(C=V, Coinage),
A >= V,
Num is floor(A / V),
B is A mod V,
change(B, Coinage, L).
我用这个coin(C, V)
术语替换了member(C=V, Coinage)
。 member/2
是让Prolog程序更具动态性的好方法,因为您可以从列表中生成解决方案,而不是咨询事实存储。看看结果:
?- change(27, [quarter=25, dime=10, nickel=5, penny=1], Change).
Change = [(quarter, 1), (penny, 2)] ;
Change = [(dime, 2), (nickel, 1), (penny, 2)] ;
Change = [(dime, 2), (penny, 7)] ;
Change = [(nickel, 5), (penny, 2)] ;
Change = [(penny, 27)] ;
false.
让我们看看我们是否应该增加一枚3美分的硬币,也许还有近期总统的脸上:
?- change(27, [quarter=25, dime=10, nickel=5, thripenny=3, penny=1], Change).
Change = [(quarter, 1), (penny, 2)] ;
Change = [(dime, 2), (nickel, 1), (penny, 2)] ;
Change = [(dime, 2), (thripenny, 2), (penny, 1)] ;
Change = [(dime, 2), (penny, 7)] ;
Change = [(nickel, 5), (penny, 2)] ;
Change = [(thripenny, 9)] ;
Change = [(penny, 27)] ;
看起来这是个好主意!
以上是关于根据现金金额和货币列表生成变更的主要内容,如果未能解决你的问题,请参考以下文章