Printing which coins are used to make a given amount - java

I am trying to use recursion to find the minimum amount of coins to make a given amount. I have code that is able to list the minimum amount of coins required, but I can't seem to find a way to print off which coins were used to come up with the solution. I've searched and found similar examples, but I can't seem to properly apply it to this.
Here is what I have thus far:
import java.util.*;
public class Coins{
public static int findMinCoins(int[] currency, int amount) {
int i, j, min, tempSolution;
min = amount;
for (i = 0; i < currency.length; i++) {
if (currency[i] == amount) {
return 1;
}
}
for (j = 1; j <= (amount / 2); j++) {
tempSolution = findMinCoins(currency, j) + findMinCoins(currency, amount - j);
if (tempSolution < min) {
min = tempSolution;
}
}
return min;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] USA =
{1, 5, 10, 25, 50};
System.out.println("Please enter an integer amount.");
int amount = in.nextInt();
int minCoins = findMinCoins(USA, amount);
System.out.println("The minimum number of coins to make " + amount + " in United States currency is " + minCoins + ".");
System.out.println("The coins used were:");
/*Print coins used to find minCoins.*/
in.close();
}
}
An example of the code running thus far:
Please enter an integer amount.
17
The minimum number of coins to make 17 in United States currency is 4.
The coins used were:
If someone could give me some insight on how to do this, it would be much appreciated.

I think this should totally work with what you want to achieve. Just call the public static int findMinCoins(arg1, arg2) and it will output you the minimum number of coins and all the particular coins(It will show times the number of its occurrence) used using recursive algorithms.
public static int findMinCoins(int[] currency, int amount) {
int min = findMinCoins(currency, amount, 0);
System.out.print("The coins used were: ");
return min;
}
private static int findMinCoins(int[] currency, int amount, int min){
int number, value1, value2;
int min1 = min;
for(int i=currency.length-1; i>=0; i--) {
if (amount>=currency[i]){
amount = amount - currency[i];
System.out.print(currency[i] + " ");
min1 = findMinCoins(currency, amount, min1);
return ++min1;
}
}
return min1;
}

Here is a recursive code (working, but need a fix ...).
The idea is to pass and array with all coins {1,5,10,25,50} and recursively call from left to right (until end of array)
NOTES :
There is a little bug in the output
The number is passed as array of 1 element instead of a primitive int. (this is to have a reference type to keep its value through all recursive calls :
public class coins {
public static void main(String[] args) {
// arrays of coin types
int[] coinTypes = { 0, 1, 5, 10, 25, 50 };
// arrays are references, so changing them
// inside the recursive function will 'really' change
int[] price = {11}; // sample input
tryBigger(price, coinTypes, 0);
}
// tries to see if higher coin is possible by passing array
// of coin types and recursively call until the end of array
public static void tryBigger(int[] price, int[] theCoins, int index) {
if (index < theCoins.length-1){
// until last element
if (price[0] > theCoins[index]){
tryBigger(price, theCoins, ++index);
}
}
// find amount of this coin
int thisCoin = price[0]/theCoins[index];
// remove the amount already got before
price[0] = price[0] - thisCoin*theCoins[index];
System.out.println(thisCoin + " coins of " + theCoins[index]);
return;
}
}

In the code you offer, either the number 1 or min are returned by the recursive function. Keeping with this method, one way you could obtain the list of coins is by altering the return variable to include both coins and count.
Here's an example of the general idea; since I don't know about programming in Java, I'll leave the implementation to you.
if (currency[i] == amount){
return [1,i];
...
temp1 = findMinCoins(currency,j);
temp2 = findMinCoins(currency,amount - j);
if(temp1[0] + temp2[0] < min[0]){
min = [temp1[0] + temp2[0]] concatenated with temp1[1..] and temp2[1..]

Here you go, you have a test and the function is below. Notice that edge cases are not handled, such as empty currency or negative amount.
It is assumed that the currency array is sorted. If not, sort it with Arrays.sort(currency).
public class FindMinimumCoinsTest {
#Test
public void test() throws Exception {
int[] USA = { 1, 5, 10, 25, 50 };
assertEquals(2, findMinCoins(USA, 11));
assertEquals(4, findMinCoins(USA, 8));
assertEquals(4, findMinCoins(USA, 111));
assertEquals(3, findMinCoins(USA, 27));
}
public static int findMinCoins(int[] currency, int amount) {
int coins = 0;
int sum = 0;
int value, n;
for (int i = currency.length - 1; i >= 0; i--) {
value = currency[i];
n = (amount - sum) / value;
if (n > 0) {
coins += n;
sum += n * value;
}
}
return coins;
}
}
Also, no need for recursion using this method ;)

I was working on something similar and this is what I came up with. You can hold the used coins in a separate array and have a helper function print the last used coins recursively. If you want to return a list or a string you can just have the helper create and return one.
/**
* FIND MINIMAL NUMBER OF COINS TO MAKE CHANGE, WITH CHANGE VALUES: 1, 2, 5, 10, 20, 50, 100, 200
*
* #param change The amount of change we need to give
* #return Minimal amount of coins used
*/
public static int minimalNumberOfCoinsToMakeChange(int change) {
int[] denominations = {1, 2, 5, 10, 20, 50, 100, 200};
int[] dp = new int[change + 1];
int[] origins = new int[change+1];
dp[0] = 0;
for (int i = 1; i <= change; i++) {
dp[i] = Integer.MAX_VALUE;
for (int coin : denominations) {
if (i - coin < 0) {
continue;
}
dp[i] = Math.min(dp[i], 1 + dp[i - coin]);
origins[i] = coin;
}
}
if (dp[change] == Integer.MAX_VALUE) {
return -1;
}
printPath(origins);
return dp[change];
}
/**
* HELPER FUNCTION - GET PATH
*
* #param origins Array with origins from main function
*/
private static void printPath(int[] origins) {
int last = origins[origins.length-1];
System.out.println(last);
origins = Arrays.copyOfRange(origins,0,origins.length-last);
if (origins.length-1 > 0){
printPath(origins);
}
}
I hardcoded the array of denominations in this example, but you should be able to remove it and pass another as argument. It is not the most efficient way, but might be helpful to people who are only just getting into dynamic programming, like I am. Cheers!

Related

CoinChange Problem with DP in Java using 2D array

I am implementing an algorithm to solve the Coin Change problem, where given an array that indicates types of coins (i.e. int[] coinValues = {1,4,6};) and a value to achieve (i.e. int totalAmount=8;), an array is returned where the value at position 0 indicates the minimum number of coins needed to achieve totalAmount. The rest of the array will keep a track of how many coins are needed to achieve the total sum.
An example input of coins = {1,4,6} and total = 8 should return the array [3,2,0,1]. However, my code is returning [1,2,0,1].
Another example would be coins = {2,4,8,16,34,40,64} and total = 50 should return the array [2, 0, 0, 0, 1, 1, 0, 0]. My code is not returning that result.
The algorithm is implemented with 2 methods: CoinChange and CoinCount. CoinChange creates the coin matrix and CoinCount keeps track of the coins required to achieve the total sum.
package P5;
import java.util.Arrays;
public class CoinChange7 {
public static int[] CoinChange(int[] v, int sum) {
int[][] aux = new int[v.length + 1][sum + 1];
// Initialising first column with 0
for(int i = 1; i <= v.length; i++) {
aux[i][0] = 0;
}
// Implementing the recursive solution
for(int i = 1; i <= v.length-1; i++) {
for(int j = 1; j <= sum; j++) {
if(i == 1) {
if(v[1] > j) {
aux[i][0]=999999999; //instead of Integer.MAX_VALUE
} else {
aux[i][j]=1 + aux[1][j-v[1]];
}
} else {
if(v[i] > j) { //choose best option ,discard this coin or use it.
aux[i][j] = aux[i - 1][j];
} else
aux[i][j] = Math.min(aux[i-1][j],1 + aux[i][j-v[i]]);
}
}
}
int []z=CoinCount(sum,aux,v);
return z; // Return solution to the initial problem
}
public static int[] CoinCount(int A, int[][] aux, int[] d){
int coin = d.length-1;
int limit=A;
int [] typo=new int[d.length+1]; //We create solution array, that will count no of coins
for (int k=0;k<typo.length;k++) {
typo[k]=0;
} while (coin>0 || limit>0){
if(limit-d[coin]>=0 && coin-1>=0){
if(1+aux[coin][limit-d[coin]]<aux[coin-1][limit]){
typo[coin+1]=typo[coin+1]+1;
limit=limit-d[coin];
} else {
coin=coin-1;
}
} else if(limit-d[coin]>=0) {
typo[coin+1]=typo[coin+1]+1;
limit=limit-d[coin];
} else if(coin-1>=0) {
coin=coin-1;
}
}
typo[0]= aux[d.length-1][A];
return typo; //return the final array with solutions of each coin
}
public static void main(String[] args) {
int[] coins = {1,4,6};
int sum = 8;
int[] x=CoinChange(coins,sum);
System.out.println("At least " + Arrays.toString(x) +" from set "+ Arrays.toString(coins)
+ " coins are required to make a value of " + sum);
}
}
Clarification
I don't know if you still need the answer to this question but I will try to answer it anyway.
First, there are a few things I would like to clarify. The coin change problem does not have a unique solution. If you want both the minimum of coins used to make the change and frequencies of coins usage, I think that depends on the approach used to solve the program and the arrangement of the coins.
For example: Take the coins to be [4,6,8] and amount = 12. You'll quickly see that the minimum coins required to make this change is 2. Going by your choice of output, the following are all correct: [2,0,2,0] and [2,1,0,1].
By the way, the Coin change problem can be solved in many ways. A simple recursive DP approach in Java is here. It only returns the min coins needed to make the change at O(nlog(n)) time and O(n) space.
Another approach is by using a 2D DP matrix (same with the approach you tried using) at both O(n^2) time and space. Explanation on how to use this approach is here. Please be careful with the explanation because it is not generally correct. I noticed it's almost the same as the one you used.
Your solution
I will mention a few things about your solution that may have affected the result.
The number of rows of the DP matrix is v.length not v.length + 1.
Based on your solution, this should not affect the result because I noticed you don't seem comfortable with zero indexes.
I think it is not necessary to initialize the first column of the DB matrix since the data type you used is int, which is 0 by default. Again, this does not affect the answer, though.
The way you filled row 1 (supposed to be the first row, but you ignored row 0) is not good and may affect the result of some solutions.
The only mistake I see there is that there is no uniform value to specify amounts (i.e. j) that cannot be solved using the single coin (i.e. v[0]). Negative numbers could have been better because any positive integer is a potential valid solution for the cell. You could use -1 (if you're going by the Leetcode instruction). This way, you'll easily know cells that contain invalid values while filling the rest of the matrix.
The way you compute aux[i][j] is wrong because you are using the wrong coins. you are using v[i] instead of v[i-1] since you aux.length is one bigger than the v.length.
I did not look at the countCoint method. It looks complex for a seemingly simple problem. Please see my solution.
My Solution
public int[] change(int[] coins, int amount){
int[][] DP = new int[coins.length][amount+1];
//fill the first column with 0
//int array contains 0 by default, so this part is not necessary
/*
for (int i = 0; i < coins.length; i++) {
DP[i][0] =0;
}
*/
//fill the first row.
//At 0th row, we are trying to find the min number of ways to change j amount using only
//one coin i.e. coins[0] (that is the meaning of DP[0][j];
for (int j = 1; j <= amount; j++) {
if(coins[0] > j || j % coins[0] != 0){
DP[0][j] = -1;
}else{
DP[0][j] = j /coins[0];
}
}
//iterate the rest of the unfilled DP
for (int i = 1; i < coins.length; i++) {
for (int j = 1; j < amount+1; j++) {
if(coins[i] > j){
DP[i][j] = DP[i-1][j];
}else {
int prev = DP[i-1][j];
int cur = 1+DP[i][j-coins[i]];
if(cur == 0){
DP[i][j] = DP[i-1][j];
} else if(prev == -1) {
DP[i][j] = 1 + DP[i][j - coins[i]];
}else{
DP[i][j] = Math.min(DP[i-1][j],1+DP[i][j-coins[i]]);
}
}
}
}
return countCoin(coins,amount,DP);
}
public int[] countCoin(int[] coins, int amount, int[][] DP){
int[] result = new int[coins.length+1];//The 1 added is to hold result.
int i = coins.length -1;
int j = amount;
//while the rest will contain counter for coins used.
result[0] = DP[i][j];
if(result[0] ==0 || result[0] ==-1)return result;
while (j > 0 ){
if(i-1 >= 0 && DP[i][j] == DP[i-1][j]){
i = i-1;
}else{
j = j - coins[i];
result[i+1] += 1;
}
}
return result;
}

DP-Coin Change result getting zero

So this is my code where I'm trying to find out the minimum number of coins to make up my target amount from unlimited supply of coins. My problem is instead of getting the required coin number, I'm getting 0. So how can I fix it. And sorry if i'm not clear. My english isn't that good :( . Here is my code:
import java.util.*;
public class CoinChangeDP{
public static int[] c = {1,2,2,5,5,5,10};
public static int amount = 15;
public static int[][] dp = new int[c.length+1][amount+1];
public static void main(String[] args){
System.out.println("Minimum number of coin required: "+CoinChange(0, amount));
}
public static int CoinChange(int index, int amount){
int n = c.length;
if(index>=n){
if(amount==0)
return 0;
else
return Integer.MAX_VALUE;
}
if(dp[index][amount]!=-1){
return dp[index][amount];
}
int ret1, ret2;
if(amount>=c[index]){
ret1 = 1+CoinChange(index, amount-c[index]);
}else{
ret1 = Integer.MAX_VALUE;
}
ret2 = CoinChange(index, amount);
dp[index][amount] = Math.min(ret1, ret2);
return dp[index][amount];
}
}
dp array is initialized with zeros, so when your first call checks:
if(dp[index][amount]!=-1){
return dp[index][amount];
}
it will return 0. Fill your dp array with -1 before calling coinChange() function:
for (int[] d : dp) {
Arrays.fill(d, -1);
}
System.out.println("Minimum number of coin required: "+CoinChange(0, amount));
EDIT:
Here is a fixed version of your function (follow the comments):
public static int CoinChange(int index, int amount){
int n = c.length;
// check if at any point we reached 0 amount (got a solution)
if (amount == 0) {
return 0;
}
// if we reached the end of the array and we still have amount > 0
if (index == n){
return Integer.MAX_VALUE;
}
// if we already processed the value for this index/amount
if (dp[index][amount] != -1){
return dp[index][amount];
}
int ret1, ret2;
if(amount >= c[index]){
// take this coin and stay on same index
ret1 = 1+CoinChange(index, amount-c[index]);
}else{
ret1 = Integer.MAX_VALUE;
}
// do not take this coin and go to next index
ret2 = CoinChange(index+1, amount);
dp[index][amount] = Math.min(ret1, ret2);
return dp[index][amount];
}
And about your question about unlimited supply, here the states are either take the coin and stay on the same index (take or leave on next call), or leave it and go to next index. The first function call will try taking or leaving the coin as long as it is <= the amount, so this will cover all the possible scenarios.

How do I pass solutions from recursive method call to calling method? (backtracking algorithm)

I'm trying to implement a backtracking algorithm to balance weights on a scale. It's for university, so there are given weights I have to use (0, 2, 7, 20, 70, 200, 700). Weights can be placed on the scale multiple times to match the input. For example: input(80) -> result(20, 20, 20, 20) or input(16) -> result(7,7,2).
I have to use backtracking and recursion.
I have difficulties understanding how to do the backtracking if a proposal is wrong. I can only step back one step, but if the right solution requires two steps back my algorithm fails.
So my method isInvalid() is checking if the sum of all counterweights is higher than the input. If so, it will remove the last weight.
I guess this is my problem. For input(16) it produces (7,7,2) --> correct.
But for input(21) it never finishes, because it tries to add 20, and then tries to add 7. Then it will be over 21 and will remove 7, but it will never remove the 20.
/* This is my backtracking algorithm */
public Proposal calc(Proposal proposal) {
Proposal result;
if(proposal.isInvalid()) return null;
if(proposal.isSolution()) return proposal;
for (int i : proposal.possibleNextSteps()) {
Proposal newProposal = new Proposal(proposal.getWeight(), proposal.getCounterWeights());
newProposal.apply(i);
result = calc(newProposal);
if (result != null) return result;
}
return null;
}
/* this is the class Proposal (only required parts) */
public class Proposal {
private int weight;
private ArrayList<Integer> counterWeights;
private static Integer[] weights = {0, 2, 7, 20, 70, 200};
public Proposal(int weight, ArrayList<Integer> counterWeights) {
this.weight = weight;
this.counterWeights = counterWeights;
Arrays.sort(weights, Collections.reverseOrder());
}
public boolean isInvalid() {
if(counterWeights.stream().mapToInt(i -> i.intValue()).sum() > weight) {
counterWeights.remove(counterWeights.size()-1);
return true;
}
return false;
}
public boolean isSolution() {
return counterWeights.stream().mapToInt(value -> value).sum() == weight;
}
public Integer[] possibleNextSteps() {
return weights;
}
public void apply(int option) {
this.counterWeights.add(option);
}
}
What am I doing wrong?
And also, is this the right way to reverse my array of weights?
Thanks!
EDIT:
I tried something different.
I changed this:
Proposal newProposal = new Proposal(proposal.getWeight()- proposal.getSum(), new ArrayList<>());
And this:
public boolean isInvalid() {
return counterWeights.stream().mapToInt(value -> value).sum() > weight;
}
So now if I follow it step by step in debug mode, it is pretty much doing what I want it to do, but it does not pass the solutions from my recursion to my previous solution, so they do not add up to a final solution.
So basically I break down the problem in smaller problems (once i find a weight that fits, I'll call the method recursively with the difference between the total weight and the solution I've already found). But how do I pass the solutions to the calling method?
In the following implementation, a solution is an array of coefficients. a coefficient at index i is the number of times the weight at position i appears in the solution.
Note that you can have several solutions giving the same total weight, this implementation gives them all. It's easy to change it to return only the first solution found.
The recursive methode void solve(int weight, int n, int total) tries for index n all integers for which the total weight is no greater than the target weight.
public class Solver {
private final int[] weights;
private int[] current;
private final List<int[]> solutions = new ArrayList<>();
public Solver(int...weights) {
this.weights = weights;
}
public int[][] solve(int weight) {
current = new int[weights.length];
solutions.clear();
solve(weight, 0, 0);
return solutions.toArray(new int[solutions.size()][]);
}
public void printSolution(int[] solution) {
int total = 0;
for (int i = 0; i < solution.length; ++i) {
for (int j = 0; j < solution[i]; ++j) {
System.out.print(weights[i] + " ");
total += weights[i];
}
}
System.out.println(" total: " + total);
System.out.println();
}
private void solve(int weight, int n, int total) {
if (n >= current.length) {
if (total == weight) {
solutions.add(current.clone());
}
} else {
solve(weight, n+1, total);
while (total < weight) {
++current[n];
total += weights[n];
solve(weight, n+1, total);
}
current[n] = 0;
}
}
}

Return several arrays from an method

I am a beginner at java, but I'm trying to learn.
This is my program i am working on, the user will enter some values, where the program sort all the even values of the index to be the variable radie and all the odd values of the index to be height no matter what the element is. Same goes for nominator och denominator in the next method. But now i am stuck and dont know how to return the arrayList. I want to return my new arrays so i can use them in my other methods. Like i said im very new at java but find it fun to work with but now i need your help. As you can see i have been using swedish words for the outprint, sorry for that.
import java.util.Scanner;
import java.util.ArrayList;
public class program
{
private static Scanner keyboard = new Scanner(System.in);
public static void main(String[] args)
{
System.out.println("-------------------------------");
System.out.println("# Test av area- och volymmetod.");
System.out.println("-------------------------------");
double result1 = area1(radie);
double result2 = area2(radie, height);
double result3 = volumeCone(radie, height);
System.out.println("Radie = " + radie + "\tHeight = " + height);
System.out.printf("Basytans area:%11.2f", result1);
System.out.println();
System.out.printf("Mantelytans area:%8.2f", result2);
System.out.println();
System.out.printf("Volym:%19.2f", result3);
System.out.println();
}
public static ArrayList<Integer> readFirstInputs(int numberOfInputs)
{
System.out.println("Please enter values, Q to quit:");
int[] inputs = new int[numberOfInputs];
ArrayList<Integer> radie = new ArrayList<Integer>();
ArrayList<Integer> height = new ArrayList<Integer>();
for(int i = 0; i < inputs.length; i++)
{
inputs[i] = keyboard.nextInt();
if (i % 2 == 0)
{
radie.add(inputs[i]);
}
else if (i % 2 != 0)
{
height.add(inputs[i]);
}
}
return ????? // return radie and height array, how?
}
public static ArrayList<Integer> readSecondInputs(int numberOfInputs)
{
System.out.println("Please enter values, Q to quit:");
int[] inputs = new int[numberOfInputs];
ArrayList<Integer> nominator = new ArrayList<Integer>();
ArrayList<Integer> denominator = new ArrayList<Integer>();
for(int i = 0; i < inputs.length; i++)
{
inputs[i] = keyboard.nextInt();
if (i % 2 == 0)
{
nominator.add(inputs[i]);
}
else if (i % 2 != 0)
{
denominator.add(inputs[i]);
}
}
return ????; // return nominator and denominator array, how?
}
/* Use my different arrays in the methods below. */
public static double area1(int radie)
{
double areaBas = Math.PI * Math.pow(radie, 2);
return areaBas;
}
public static double area2(int radie, int height)
{
double areaMantel = Math.PI * radie * Math.sqrt((Math.pow(radie, 2) + Math.pow(height, 2)));
return areaMantel;
}
public static double volumeCone(int radie, int height)
{
double volume = Math.PI * Math.pow(radie, 2) * height / 3;
return volume;
}
public static int fractionToInteger(int nominator, int denominator)
{
int amount = nominator / denominator;
return amount;
}
public static int fractionToFraction(int nominator, int denominator)
{
int remainingAmount = nominator % denominator;
return remainingAmount;
}
}
Are you allowed to use a list instead? it's way more efficient since once created, you can't change the size of an array, but if you instead create two empty lists you can just use the .add method that lists have, looking similar to this:
public static List<Integer> readFirstInputs(int numberOfInputs)
{
System.out.println("Please enter values, Q to quit:");
int[] inputs = new int[numberOfInputs];
List<Integer> evens = new List<Integer>();
List<Integer> odds = new List<Integer>();
for(int i = 0; i < inputs.length; i++)
{
inputs[i] = keyboard.nextInt();
if (i % 2 == 0)
{
evens.add(inputs[i]);
}
else if (i % 2 != 0)
{
odds.add(inputs[i]);
}
}
}
of course I am a bit confused on exactly what you want to do so you are definitely gonna have to change this up a bit, I just want to use this as a basic example of how to use a list instead.
If I understand you correctly, you would like to return from the function an array of odd numbers and an array of even numbers from user input.
but you are returning only one array which is just an array of the users inputs (with no logical meaning for the conditions in the loop).
from what I know - it is not possible to return 2 arrays, but there are solutions of course. you can return a class or a dictionary, for example.
if you choose a dictionary it will be something like Dictionary<string,object>, and will have 2 items, the string will be "odd" \ "even", and the object will be the matching array of the numbers (int[] or List<int>). odd numbers array a value of "odd" key, and even numbers array a value of "even" key in the dictionary.
two problems that appear to me here other than that:
1.) you are trying to use 2 variables that are not defined or even mentioned in the function (even and odd).
2.) in each condition you wrote return. this will exit the loop and function on the first iteration.
hope this was helpfull.

Dynamic Programming - Minimum number of coins needed for given sum

After researching the Coin Change problem I tried my best to implement the solution. The code I have so far prints the minimum number of coins needed for a given sum. However, it does not print out the number of each coin denomination needed. This is what my code currently looks like:
public class Coins {
static int minCoins(int coinValues[], int m, int target) {
int[] totalCoins = new int[target + 1];
int[][] numOfCoins = new int[target + 1][m];
totalCoins[0] = 0;
for (int i = 1; i <= target; i++) {
totalCoins[i] = Integer.MAX_VALUE;
}
for (int i = 1; i <= target; i++) {
for (int j = 0; j < m; j++) {
if (coinValues[j] <= i) {
int previous = totalCoins[i - coinValues[j]];
if (previous != Integer.MAX_VALUE && previous + 1 < totalCoins[i]) {
totalCoins[i] = previous + 1;
}
}
}
}
return totalCoins[target];
}
public static void main(String args[]) {
int coinValues[] = {1, 5, 10, 20};
int m = coinValues.length;
int target = 26;
System.out.println("Minimum coins required is "+ minCoins(coinValues, m, target) );
}
}
I'm just very confused how/where I should populate numOfCoins[][].
Solution that I implemented in Groovy using Euro denominations
class coinage {
def denoms = [1, 2, 5, 10, 20, 50, 100, 200]
def resultArray = []
def remainder
def largest
def newResult
def calculate(int amt) {
def value = denoms.findAll({ element -> element <= amt})
largest = value.last()
resultArray.add(largest)
remainder = amt - largest
if (remainder == 0 || remainder == amt) {
newResult = resultArray.size()
println("Minimum number of coins required for this is: $newResult")
} else
calculate(remainder)
}
}
And to call it:
coins = new coinage()
coins.calculate(305)
#user1523236 provides the greedy method which does not solve the general case. For example, if one removes the 1 denomination and calculates the change for 8.
Please take a look at, for example, 4.12. Dynamic Programming, or The dynamic programming alogorithm for CMP (change making problem). Both references provide general dynamic programming algorithms.

Categories