3

My assignment is to find a way to display all possible ways of giving back change for a predetermined value, the values being scanned in from a txt file. This must be accomplished by Recursive Backtracking otherwise my solution will not be given credit. I will be honest in saying I am completely lost on how to code in the appropriate algorithm. All I know is that the algorithm works something like this:

 start with empty sets.
 add a dime to one set. 
 subtract '10' from my amount.
 This is a negative number, so I discard that set: it is invalid.
 add a nickel to another (empty) set.
 subtract '5' from my amount.
This equals 2; so I'll have to keep working on this set. 
Now I'm working with sets that already include one nickel.
add a dime to one set.
subtract '10' from my amount.
This is a negative number, so I discard that set: it is invalid.
repeat this with a nickel; I discard this possibility because (2 - 5) is also negative.
repeat this with a penny; this is valid but I still have 1 left.
repeat this whole process again with a starting set of one nickel and one penny, 
   again discarding a dime and nickel, 
   and finally adding a penny to reach an amount of 0: this is a valid set.
Now I go back to empty sets and repeat starting with a nickel, then pennies.

The issue is I haven't the slightest clue on how or where to begin, only that that has to be accomplished, or if any other solutions are apparent.

This is my code thus far:

UPDATED

import java.io.*;
import java.util.*;
import java.lang.*;

public class homework5 {

 public static int penny = 1;
 public static int nickle = 5;
 public static int dime = 10;
 public static int quarter = 25;
 public static int halfDollar = 50;
 public static int dollar = 100;
 public static int change;

  public static void main(String[] args) throws FileNotFoundException {

    ArrayList<Integer> coinTypes = new ArrayList<Integer>();

    Integer i;
    File f = new File (args[0]);
    Scanner input = new Scanner(f);
       input.nextLine();
       while(input.hasNextInt()) {
               i = input.nextInt();
               coinTypes.add(i);
       }
       change = coinTypes.get(coinTypes.size()-1);
       coinTypes.remove(coinTypes.size()-1);
                System.out.println("Found change"); //used for debugging
                System.out.println("Change: " + change);


    System.out.println(coinTypes);
  }
     boolean findChange(int change, List<Integer> coinTypes,
                     List<Integer> answerCoins) {
        if(change == 0) {
          return true;
        }
        if(change < 0) {
          return false;
        } else {
          for(Integer coin : coinTypes) {
              if(findChange(change - coin, coinTypes, answerCoins)){
                 answerCoins.add(coin);
                 return true;
              }
          }

  List<Integer> answer = new ArrayList<Integer>();
   boolean canFindChange = findChange(change, coinTypes, answer);
    if(canFindChange) {
        System.out.println(answer);
    } else { System.out.println("No change found");
      }
   return false;
  }
}

Here is the input file that I scan in

java homework5 hwk5sample1.txt

// Coins available in the USA, given in cents.  Change for $1.43?
1 5 10 25 50 100
143

OUTPUT

Found change
Change: 143
[1, 5, 10, 25, 50, 100]

So using the numbers in my coinTypes ArrayList, I need a generic code algorithm to show all possible ways of receiving, for example, 143 ($1.43) back in change using the coins in the file with all pennies being the last way to show it.

Please do not think I want you to write me the algorithm, I am simply wanting help writing one otherwise I will learn nothing. Thank you all for any answers or help you can give it means a lot to me! Please let me know if i missed anything or you need more info

Junikin
  • 301
  • 2
  • 14

1 Answers1

4

The example that you walk through seems to be mostly correct. The only error is this: again discarding a dime and nickel, which should be again discarding a *penny* and nickel (but I think that's just a typo.)

To write a recursive backtracking algorithm, it is useful to think of the recursive call as solving a subproblem of the original problem. In one possible implementation of the solution, the pseudocode looks like this:

/**
 * findChange returns true if it is possible to make *change* cents of change
 *     using the coins in coinTypes. It adds the solution to answerCoins.
 *     If it's impossible to make this amount of change, then it returns false.
 */
boolean findChange(int change, List<Integer> coinTypes, List<Integer> answerCoins) {
    if change is exactly 0: then we're done making change for 0 cents! return true
    if change is negative: we cannot make change for negative cents; return false
    otherwise, for each coin in coinTypes {
        // we solve the subproblem of finding change for (change - coin) cents
        // using the recursive call.
        if we can findChange(change - coin, coinTypes, answerCoins) {
            // then we have a solution to the subproblem of
            // making (change - coins) cents of change, so:
            - we add coin to answerCoins, the list of coins that we have used
            - we return true // because this is a solution for the original problem
        }
    }
    //if we get to the next line, then we can't find change for any of our subproblems
    return false
}

We would call this method with:

List<Integer> answer = new ArrayList<Integer>();
boolean canFindChange = findChange(change, coinTypes, answer);
if(canFindChange) {
    System.out.println(answer); // your desired output.
}
else {
    System.out.println("Can't find change!");
}
irrelephant
  • 4,091
  • 2
  • 25
  • 41
  • No, you have not added the most crucial part of this algorithm, which is the recursive calls. Don't just guess what to do -- think about what you are trying to accomplish through code. – irrelephant Nov 24 '14 at 03:13
  • Ah, sorry, it looks like my phone didn't update the question. You almost have it, but you just need to think about how to manage answerCoins, which should contain the solution at the end. – irrelephant Nov 24 '14 at 03:20
  • Yes, and if you could use the chat room, that would be great. You should have enough rep now. – irrelephant Nov 24 '14 at 03:23
  • In your answer it says `answerCoins + [coin]` i was a little confused by what you mean by this because you can't exactly add a List to an int? Right? What did you mean when you wrote that? – Junikin Nov 24 '14 at 03:24
  • Ok you might have to reinvite me because I am new to this site and don't know how – Junikin Nov 24 '14 at 03:24
  • By answerCoins + [coin], I just meant that we are appending the value coin to answerCoins. This is Python-esque pseudocode. – irrelephant Nov 24 '14 at 03:27
  • Ok so what would that look like in java? – Junikin Nov 24 '14 at 03:29
  • Well, you should figure it out. Remember that answerCoins keeps track of the coin values that we have used do far in our recursion. – irrelephant Nov 24 '14 at 03:33
  • What can I look at that might help me figure it out, I'm kinda of not following. Thank you by the way for your tremendous amount of time and patience to help a beginner like me – Junikin Nov 24 '14 at 03:38
  • Please see [the chat room](http://chat.stackoverflow.com/rooms/65491/discussion-between-irrelephant-and-junikin). – irrelephant Nov 24 '14 at 04:07
  • is perhaps simply `answerCoins.add(coin);`? – Junikin Nov 24 '14 at 04:12
  • Sorry was downvoted, I was gonna say when I try calling `findChange(change, coinTypes, answerCoins);` in main, it says answerCoins not found – Junikin Nov 24 '14 at 07:45
  • Also even if it did work, wouldn't i get a message saying it can't be referenced from static context? – Junikin Nov 24 '14 at 07:53