[Solved] reaching the goal number [closed]


I would take a dynamic-programming approach:

def fewest_items_closest_sum_with_repetition(items, goal):
    """
    Given an array of items
      where each item is 0 < item <= goal
      and each item can be used 0 to many times

    Find the highest achievable sum <= goal

    Return any shortest (fewest items) sequence
      which adds to that sum.
    """
    assert goal >= 0, "Invalid goal"
    # remove any duplicate or invalid items
    items = set(item for item in items if 0 < item <= goal)
    # sort descending (work with largest values first)
    items = sorted(items, reverse=True)

    # start with the no-item sequence
    best   = {0: []}
    active = {0: []}
    # while we have further seeds to work from
    while active:
        nactive = {}
        for item in items:
            for total, seq in active.items():
                # find next achievable sum
                ntotal = total + item
                # if it is a valid subgoal and has not already been found
                if (ntotal <= goal and ntotal not in best):
                    # save it
                    best[ntotal] = nactive[ntotal] = [item] + seq
                    if ntotal == goal:
                        # best possible solution has been found!
                        break
        active = nactive

    # return the best solution found
    return best[max(best)]

which then runs like

>>> fewest_items_closest_sum_with_repetition([2,3,4,7,20,25], 105)
[25, 20, 20, 20, 20]

>>> fewest_items_closest_sum_with_repetition((40,79), 80)
[40, 40]

solved reaching the goal number [closed]