# coins: A list with the values of the coins we're using
# myCoins: Index into the coins list of the current coin
# amountNeeded: Our current goal for number of cents
# coinsUsed: A list of the number of each coin used thus far. Mostly
# for sanity checking and printing all of the combinations.
# check: If this is true, sanity checking is performed.
def combinationsOfCoinsRec( coins, myCoin, amountNeeded, coinsUsed, check ):
if amountNeeded == 0:
# We've reached our desired value exactly, so return that this
# combination is valid.
# If check is true, perform sanity checking first and print coinsUsed
if check:
coinVal = 0
for i in range(len(coinsUsed)):
coinVal += coinsUsed[i] * coins[i]
assert(coinVal == 100)
print "{0} = {1}".format(coinsUsed, coinVal)
return 1
if amountNeeded < 0 or myCoin >= len(coins):
# We don't have any more coin types or we went over our desired value,
# so this is not a valid combination
return 0
# If we've gotten this far, we haven't met our desired amount yet, so
# let's see how many combinations we can find that use various amounts
# of our coin.
combinations = 0
# This is the maximum number of our coin that it makes sense to try
maxNumOurCoin = amountNeeded / coins[myCoin]
# Note: we add 1 to the range because the range function gives us all
# values from 0 up to the value we specify, but not including it.
for numCoins in range( maxNumOurCoin + 1 ):
newNeeded = amountNeeded - (coins[myCoin] * numCoins)
# Append the number of our coin we used for sanity checking.
newCoinsUsed = list(coinsUsed)
newCoinsUsed.append(numCoins)
# Add the number of combinations of other coins we haven't used yet
# that bring us to the desired value
combinations += combinationsOfCoinsRec( coins, myCoin + 1, newNeeded, newCoinsUsed, check )
return combinations
# Just a helper function that initializes all of the extra stuff for the
# recursive function
def combinationsOfCoins( coins, amountDesired, check = False ):
if amountDesired < 0:
raise RuntimeError("You can't desire a negative number of coins, silly!")
return combinationsOfCoinsRec( coins, 0, amountDesired, [], check )
# Set up the coins we're going to use
coinValues = [100, 50, 25, 10, 5, 1]
desiredCents = 100
print combinationsOfCoins( coinValues, desiredCents )
IyBjb2luczogICAgICAgICAgICBBIGxpc3Qgd2l0aCB0aGUgdmFsdWVzIG9mIHRoZSBjb2lucyB3ZSdyZSB1c2luZwojIG15Q29pbnM6ICAgICAgICAgIEluZGV4IGludG8gdGhlIGNvaW5zIGxpc3Qgb2YgdGhlIGN1cnJlbnQgY29pbgojIGFtb3VudE5lZWRlZDogICAgIE91ciBjdXJyZW50IGdvYWwgZm9yIG51bWJlciBvZiBjZW50cwojIGNvaW5zVXNlZDogICAgICAgIEEgbGlzdCBvZiB0aGUgbnVtYmVyIG9mIGVhY2ggY29pbiB1c2VkIHRodXMgZmFyLiBNb3N0bHkKIyAgICAgICAgICAgICAgICAgICBmb3Igc2FuaXR5IGNoZWNraW5nIGFuZCBwcmludGluZyBhbGwgb2YgdGhlIGNvbWJpbmF0aW9ucy4KIyBjaGVjazogICAgICAgICAgICBJZiB0aGlzIGlzIHRydWUsIHNhbml0eSBjaGVja2luZyBpcyBwZXJmb3JtZWQuCmRlZiBjb21iaW5hdGlvbnNPZkNvaW5zUmVjKCBjb2lucywgbXlDb2luLCBhbW91bnROZWVkZWQsIGNvaW5zVXNlZCwgY2hlY2sgKToKICAgIGlmIGFtb3VudE5lZWRlZCA9PSAwOgogICAgICAgICMgV2UndmUgcmVhY2hlZCBvdXIgZGVzaXJlZCB2YWx1ZSBleGFjdGx5LCBzbyByZXR1cm4gdGhhdCB0aGlzCiAgICAgICAgIyBjb21iaW5hdGlvbiBpcyB2YWxpZC4KCiAgICAgICAgIyBJZiBjaGVjayBpcyB0cnVlLCBwZXJmb3JtIHNhbml0eSBjaGVja2luZyBmaXJzdCBhbmQgcHJpbnQgY29pbnNVc2VkCiAgICAgICAgaWYgY2hlY2s6CiAgICAgICAgICAgIGNvaW5WYWwgPSAwCiAgICAgICAgICAgIGZvciBpIGluIHJhbmdlKGxlbihjb2luc1VzZWQpKToKICAgICAgICAgICAgICAgIGNvaW5WYWwgKz0gY29pbnNVc2VkW2ldICogY29pbnNbaV0KICAgICAgICAgICAgYXNzZXJ0KGNvaW5WYWwgPT0gMTAwKQoKICAgICAgICAgICAgcHJpbnQgInswfSA9IHsxfSIuZm9ybWF0KGNvaW5zVXNlZCwgY29pblZhbCkKCiAgICAgICAgcmV0dXJuIDEKCiAgICBpZiBhbW91bnROZWVkZWQgPCAwIG9yIG15Q29pbiA+PSBsZW4oY29pbnMpOgogICAgICAgICMgV2UgZG9uJ3QgaGF2ZSBhbnkgbW9yZSBjb2luIHR5cGVzIG9yIHdlIHdlbnQgb3ZlciBvdXIgZGVzaXJlZCB2YWx1ZSwKICAgICAgICAjIHNvIHRoaXMgaXMgbm90IGEgdmFsaWQgY29tYmluYXRpb24KICAgICAgICByZXR1cm4gMAoKICAgICMgSWYgd2UndmUgZ290dGVuIHRoaXMgZmFyLCB3ZSBoYXZlbid0IG1ldCBvdXIgZGVzaXJlZCBhbW91bnQgeWV0LCBzbwogICAgIyBsZXQncyBzZWUgaG93IG1hbnkgY29tYmluYXRpb25zIHdlIGNhbiBmaW5kIHRoYXQgdXNlIHZhcmlvdXMgYW1vdW50cwogICAgIyBvZiBvdXIgY29pbi4KICAgIGNvbWJpbmF0aW9ucyA9IDAKCiAgICAjIFRoaXMgaXMgdGhlIG1heGltdW0gbnVtYmVyIG9mIG91ciBjb2luIHRoYXQgaXQgbWFrZXMgc2Vuc2UgdG8gdHJ5CiAgICBtYXhOdW1PdXJDb2luID0gYW1vdW50TmVlZGVkIC8gY29pbnNbbXlDb2luXQoKICAgICMgTm90ZTogd2UgYWRkIDEgdG8gdGhlIHJhbmdlIGJlY2F1c2UgdGhlIHJhbmdlIGZ1bmN0aW9uIGdpdmVzIHVzIGFsbAogICAgIyB2YWx1ZXMgZnJvbSAwIHVwIHRvIHRoZSB2YWx1ZSB3ZSBzcGVjaWZ5LCBidXQgbm90IGluY2x1ZGluZyBpdC4KICAgIGZvciBudW1Db2lucyBpbiByYW5nZSggbWF4TnVtT3VyQ29pbiArIDEgKToKICAgICAgICBuZXdOZWVkZWQgPSBhbW91bnROZWVkZWQgLSAoY29pbnNbbXlDb2luXSAqIG51bUNvaW5zKQoKICAgICAgICAjIEFwcGVuZCB0aGUgbnVtYmVyIG9mIG91ciBjb2luIHdlIHVzZWQgZm9yIHNhbml0eSBjaGVja2luZy4KICAgICAgICBuZXdDb2luc1VzZWQgPSBsaXN0KGNvaW5zVXNlZCkKICAgICAgICBuZXdDb2luc1VzZWQuYXBwZW5kKG51bUNvaW5zKQoKICAgICAgICAjIEFkZCB0aGUgbnVtYmVyIG9mIGNvbWJpbmF0aW9ucyBvZiBvdGhlciBjb2lucyB3ZSBoYXZlbid0IHVzZWQgeWV0CiAgICAgICAgIyB0aGF0IGJyaW5nIHVzIHRvIHRoZSBkZXNpcmVkIHZhbHVlCiAgICAgICAgY29tYmluYXRpb25zICs9IGNvbWJpbmF0aW9uc09mQ29pbnNSZWMoIGNvaW5zLCBteUNvaW4gKyAxLCBuZXdOZWVkZWQsIG5ld0NvaW5zVXNlZCwgY2hlY2sgKQoKICAgIHJldHVybiBjb21iaW5hdGlvbnMKCiMgSnVzdCBhIGhlbHBlciBmdW5jdGlvbiB0aGF0IGluaXRpYWxpemVzIGFsbCBvZiB0aGUgZXh0cmEgc3R1ZmYgZm9yIHRoZQojIHJlY3Vyc2l2ZSBmdW5jdGlvbgpkZWYgY29tYmluYXRpb25zT2ZDb2lucyggY29pbnMsIGFtb3VudERlc2lyZWQsIGNoZWNrID0gRmFsc2UgKToKICAgIGlmIGFtb3VudERlc2lyZWQgPCAwOgogICAgICAgIHJhaXNlIFJ1bnRpbWVFcnJvcigiWW91IGNhbid0IGRlc2lyZSBhIG5lZ2F0aXZlIG51bWJlciBvZiBjb2lucywgc2lsbHkhIikKCiAgICByZXR1cm4gY29tYmluYXRpb25zT2ZDb2luc1JlYyggY29pbnMsIDAsIGFtb3VudERlc2lyZWQsIFtdLCBjaGVjayApCgojIFNldCB1cCB0aGUgY29pbnMgd2UncmUgZ29pbmcgdG8gdXNlCmNvaW5WYWx1ZXMgPSBbMTAwLCA1MCwgMjUsIDEwLCA1LCAxXQpkZXNpcmVkQ2VudHMgPSAxMDAKCnByaW50IGNvbWJpbmF0aW9uc09mQ29pbnMoIGNvaW5WYWx1ZXMsIGRlc2lyZWRDZW50cyAp