-1

For one of my classes, we had to find a way to make a certain amount of change given an arbitrary amount of coins, with the least amount of coins. Here is my code below:

public class Changemaker {

public static void main ( String[] args ) {
    int amount = Integer.parseInt(args[args.length-1]);
    int coins = args.length - 1;

    if (amount < 0){
        throw new IllegalArgumentException("IMPROPER AMOUNT"); 

    } else {

        for (int i = 1; i <= coins; i++) {
            int coin = Integer.parseInt(args[i]);

            if (coin <= 0){
                throw new IllegalArgumentException("IMPROPER DENOMINATION"); 

            } else {

                for (int j = 1; j <= coins; j++) {
                    int validCoin = Integer.parseInt(args[j]);

                    if (validCoin == coin && j != i ) {
                        throw new IllegalArgumentException("DUPLICATE DENOMINATION");

                    }
                }
            }

            try { 
                String firstCoin = args[1];

            } catch (ArrayIndexOutOfBoundsException e) { 
                System.out.println("INSUFFICIENT DATA"); 
                throw new ArrayIndexOutOfBoundsException(" ");

            } 
        }
    }



    Tuple [][] table = new Tuple [coins][amount + 1];

    for(int x = 0; x < coins; x++) {
        for (int i = 0; i <= amount; i++) {
            Tuple tuple = new Tuple (coins);
            table[x][i] = tuple;

        }
    }


    for (int i = 1; i <= amount; i++) {
        Tuple tuple = table[0][i];
        int coin = Integer.parseInt(args[1]);
        int total = i;
        int remainder = total % coin;
        int coinAmt= (int)Math.floor(total / coin);

        if (remainder == 0) {
            tuple.setElement(0, coinAmt);
        }

    }


    for(int x = 1; x < coins; x++) {
        int coin = Integer.parseInt(args[x + 1]);

        for (int i = 1; i <= amount; i++) {
            Tuple tuple = table[x][i];
            int total = i;
            int remainder = total % coin;
            int coinAmt= (int)Math.floor(total / coin);

            if (remainder == 0) { 

                tuple.setElement(x, coinAmt);
                int optimalRow = optimalCheck(table, tuple, x, i);

                Tuple optimalTuple = table[optimalRow][i];


                tuple.copy(optimalTuple);

            } else if (remainder != 0 && amount < coin) { 

                tuple.copy(table[x - 1][i]);

            } else if (remainder != 0 && amount > coin) { 

                tuple.setElement(x, coinAmt);
                Tuple remainderTuple = table[x][remainder];
                tuple.add(remainderTuple);

                int optimalRow = optimalCheck(table, tuple, x, i);
                Tuple optimalTuple = table[optimalRow][i];
                tuple.copy(optimalTuple);

            }
        }
    }

    Tuple finalAnswer = table[coins - 1][amount];

    String result = "";
    result = result + finalAnswer.total() + " COIN(S) IN TOTAL: ";

    for (int i = 0; i < coins; i++) {
        result = result + finalAnswer.getElement(i) + " x " + args[i + 1] + " cent , ";

    }


    if (finalAnswer.total() == 0) {
        System.out.println("AMOUNT CANNOT BE MADE");

    } else {
        System.out.println(result);

    }

}



public static int optimalCheck(Tuple[][] table, Tuple tuple, int row, int column) {
    int total = tuple.total();
    int optimalRow = 0;

    for (int i = 0; i <= row; i++ ){
        int checkedTotal = table[i][column].total();    

        if (checkedTotal < total && checkedTotal > 0) {
            optimalRow = optimalRow + i;
            break;
        } else if (checkedTotal == total && i == row) {
            optimalRow = optimalRow + row;
            break;
        }
    }

    return optimalRow;
} }

For the most part, my code is correct. The only thing wrong with it is that it counts the amount of change to make as a denomination, and it cuts out my first denomination amount.

So, for example, if I put 1 5 10 25 133 in the command line (1,5,10, and 25 cent coins to make 133 cents), it returns:

1 COIN(S) IN TOTAL: 0 x 5 cent , 0 x 10 cent , 0 x 25 cent , 1 x 133 cent ,

I looked at the code, and I don't see where I went wrong. Can anyone tell me where I made the error? Thanks a ton.

J-Play
  • 29
  • 1
  • 6

1 Answers1

1

In your for loop, you want

for (int i = 1; i < coins; i++) { 

not

for (int i = 1; i <= coins; i++) {

<= will include coins, which is length - 1 - the last argument.

matt forsythe
  • 3,863
  • 1
  • 19
  • 29