Related to this question and this answer, I would like to have a second review from you on a modified version.
The problem I tried to solve
Some kind of "Minimum count of numbers required from given array to represent S" (see here).
Algorithms that I used
Some kind of dynamic programming array (see here), but I don't know the exact name.
Java Code
import java.util.Arrays;
public class CashMachineWithDynamicProgrammingArray {
private final int[] billValues;
private final int[] billAmounts;
private final int maxBillAmount;
private int currentBillAmountIndex = 0;
public CashMachineWithDynamicProgrammingArray(final int[] billValues, final int maxDepth) {
this.billValues = billValues;
billAmounts = new int[billValues.length];
maxBillAmount = maxDepth;
}
private boolean next() {
billAmounts[currentBillAmountIndex]++;
if (billAmounts[currentBillAmountIndex] >= maxBillAmount) {
do {
billAmounts[currentBillAmountIndex] = 0;
currentBillAmountIndex++;
if (currentBillAmountIndex >= billAmounts.length) {
currentBillAmountIndex = 0;
return false;
}
} while (billAmounts[currentBillAmountIndex] >= maxBillAmount);
billAmounts[currentBillAmountIndex]++;
currentBillAmountIndex = 0;
}
return true;
}
private void skipCurrentBillIndexIncrementation() {
billAmounts[currentBillAmountIndex] = maxBillAmount;
}
private int calculateBillsAmount() {
int amount = 0;
for (int i = 0; i < billValues.length; i++) {
amount += billValues[i] * billAmounts[i];
}
return amount;
}
private int calculateBillsSum() {
int sum = 0;
for (final int billAmount : billAmounts) {
sum += billAmount;
}
return sum;
}
public int[] calculateBillAmountsWithLowestSum(final int amountToLookFor) {
int lowestSum = 0;
int[] billAmountsWithLowestSum = new int[billValues.length];
do {
int amount = calculateBillsAmount();
if (amount >= amountToLookFor) {
if (amount == amountToLookFor) {
int sum = calculateBillsSum();
if (lowestSum == 0 || sum < lowestSum) {
lowestSum = sum;
System.arraycopy(billAmounts, 0, billAmountsWithLowestSum, 0, billAmounts.length);
}
}
skipCurrentBillIndexIncrementation();
}
} while (next());
return billAmountsWithLowestSum;
}
public static void main(final String[] args) {
int[] billValues = {1, 29, 59, 109, 209, 509, 1000, 2000, 5000};
int maxDepth = 5;
CashMachineWithDynamicProgrammingArray cashMachine = new CashMachineWithDynamicProgrammingArray(billValues, maxDepth);
System.out.println(Arrays.toString(cashMachine.calculateBillAmountsWithLowestSum(1)));
System.out.println(Arrays.toString(cashMachine.calculateBillAmountsWithLowestSum(30)));
System.out.println(Arrays.toString(cashMachine.calculateBillAmountsWithLowestSum(5000)));
System.out.println(Arrays.toString(cashMachine.calculateBillAmountsWithLowestSum(25114)));
}
}