1- :- use_module (library(clpfd )).
2-
3- generate_upper_constraint (_ , [] , [] ).
4- generate_upper_constraint (Max , [Coin |Coins ], [Amount |Amounts ]) :-
5- Amount in 0 . .Max,
6- generate_upper_constraint (Coin , Coins , Amounts ).
1+ fewest_coins (Coins , Target , Change ) :-
2+ make_change(Target , Coins , [] , Change ).
73
8- coins ([] , [] , [] ).
9- coins ([Coin |Coins ], [Amount |Amounts ], Change ) :-
10- length(CoinChange , Amount ),
11- maplist(= (Coin ), CoinChange ),
12- coins(Coins , Amounts , Rest ),
13- append(CoinChange , Rest , Change ).
4+ make_change (Val , Coins , Wallet , Change ) :-
5+ ( Val =:= 0
6+ -> sort(0, @=<, Wallet , Change )
7+ ; include(choose(Val , Coins ), Coins , Chosen ),
8+ ( max_list(Chosen , Coin )
9+ ; min_list(Coins , Coin ), Coin =< Val
10+ ), ! ,
11+ append(Wallet , [Coin ], Ching ),
12+ make_change(Val - Coin , Coins , Ching , Change )
13+ ).
1414
15- fewest_coins (Coins , Target , Change ) :-
16- Target #>= 0 ,
17- reverse(Coins , ReversedCoins ),
18- [Coin |_ ] = ReversedCoins ,
19- length(Coins , N ),
20- length(Amounts , N ),
21- Max #= div(Target , Coin ),
22- generate_upper_constraint(Max , ReversedCoins , ReversedAmounts ),
23- reverse(ReversedAmounts , Amounts ),
24- scalar_product(Coins , Amounts , #= , Target ),
25- sum(Amounts , #= , TotalCoins ),
26- labeling([min(TotalCoins )], Amounts ),
27- coins(Coins , Amounts , Change ),
28- ! .
15+ choose (Val , Coins , Coin ) :-
16+ Coin =< Val ,
17+ Diff is Val - Coin ,
18+ ( Diff =:= 0
19+ ; \+ include({Diff }/[C ]>> (C > 1 , 0 is Diff mod C ), Coins , [] )
20+ ).
0 commit comments