RayMan
RayMan

Reputation: 133

How can I eliminate one of the arguments in this function?

I want to eliminate the third argument in my code below which is just an empty array that I think I should be able to create as a local variable within the function itself.

As a bonus, I would also like to build this into a single function although I don't think this can be achieved with the current recursive structure of the code.

I tried creating an empty array as a local variable (See the commented out integers list)

I also tried to create a count variable to increment with each combination found (See the commented out count variable)

def count_combinations(number, integers_available, integers):

    coin_set = []
    # integers = []
    # count = 0

    if sum(integers) == number:
        coin_set.append(integers)
        # count += 1

    elif sum(integers) > number:
        pass

    elif integers_available == []:
        pass

    else:
        for c in count_combinations(number, integers_available[:], integers + [integers_available[0]]):
            coin_set.append(c)
            # count += 1
        for c in count_combinations(number, integers_available[1:], integers):
            coin_set.append(c)
            # count += 1

    # return count += 1
    return coin_set

def count_total(number, integers_available, integers):
    return len(count_combinations(number, integers_available, integers))

# Testing the code
number = 15
integers_available = [1, 5, 10]
print(count_total(number, integers_available, []))

I expect to get the same results but with fewer arguments in the function since one of the arguments will have been switched to a local variable instead.

Upvotes: 1

Views: 73

Answers (2)

wim
wim

Reputation: 362796

As discussed in the comments, a dynamic programming approach may be more Pythonic here.

from collections import Counter

def ways(total, coins=(1,2,5,10,20,50,100)):
    counts = [[Counter()]] + [[] for _ in range(total)]
    for coin in coins:
        for i in range(coin, total + 1):
            counts[i] += [c + Counter({coin: 1}) for c in counts[i-coin]]
    return counts[total]

Demo:

>>> ways(15, coins=(1,5,10))
[Counter({1: 15}),
 Counter({1: 10, 5: 1}),
 Counter({1: 5, 5: 2}),
 Counter({5: 3}),
 Counter({1: 5, 10: 1}),
 Counter({5: 1, 10: 1})]
>>> len(ways(15, coins=(1,5,10)))
6

Upvotes: 3

sam46
sam46

Reputation: 1271

Without regard to the algorithm or the goal of the code, here's how you can tidy it up a little by making it into a single function and giving integers parameter a default value:

def count_total(number, integers_available):
    def count_combinations(number, integers_available, integers=[]):
        coin_set = []
        # integers = []
        # count = 0

        if sum(integers) == number:
            coin_set.append(integers)
            # count += 1

        elif sum(integers) > number:
            pass

        elif integers_available == []:
            pass

        else:
            for c in count_combinations(number, integers_available[:], integers + [integers_available[0]]):
                coin_set.append(c)
                # count += 1
            for c in count_combinations(number, integers_available[1:], integers):
                coin_set.append(c)
                # count += 1

        # return count += 1
        return coin_set

    return len(count_combinations(number, integers_available))

# Testing the code
number = 15
integers_available = [1, 5, 10]
print(count_total(number, integers_available))

Upvotes: 0

Related Questions