# L-9 MCS 275 Mon 4 Feb 2008 : knapsack.py
#
# a simple solution to the knapsack problem

def write(s,L):
   """
   does formatted printing in knapsack
   """
   t = 'V(' + str(s) + ') = '
   for i in range(0,len(L)):
      if i > 0: t = t + ' + '
      t = t + '%.2f' % L[i]
   t = t + ' = ' + '%.2f' % sum(L)
   print t

def knapsack(V,lb,ub,k,s,L):
   """
   Shows all selections s of V whose sum
   of values in L: lb <= sum(L) <= ub.
   Input parameters:
     V     a list of values;
     lb    lower bound on sum;
     ub    upper bound on sum;
     k     index to current object.
   Accumulating parameters:
     s     stores selection of objects;
           if selected i-th object in V,
           then s[i] == 1, else s[i] == 0;
     L     values of selected objects.
   Initialize s and L both to [], k to 0.
   """
   if k >= len(V):
      if lb <= sum(L) <= ub:
         write(s,L)
   if k < len(V):
      if sum(L) + V[k] <= ub:
         s.append(k)
         L.append(V[k])
         knapsack(V,lb,ub,k+1,s,L)
         del s[len(s)-1]
         del L[len(L)-1]
      knapsack(V,lb,ub,k+1,s,L)

def main():
   """
   prompts user for number n of objects
   asks for the list of their values,
   a lower and an upper bound on the sum
   """
   n = input('give number of objects : ')
   s = 'give a list of %d values : ' % n
   V = input(s)
   lb = input('lower bound on sum : ')
   ub = input('upper bound on sum : ')
   knapsack(V,lb,ub,0,[],[])

main()
