


"""simple docstring"""





def    _snake_case  (  _snake_case :	str       ,      _snake_case :	int       ,      _snake_case :	str       ,      _snake_case :	Dict	):
      global f  # a global dp table for knapsack
      if f[i][j] < 0:
            if j < wt[i - 1]:
                  lowerCAmelCase    :		Union[str, Any]				=      mf_knapsack(i - 1       ,      _snake_case       ,      _snake_case       ,      _snake_case	)
            else:
                  lowerCAmelCase    :		Any				=      max(
                      mf_knapsack(i - 1       ,      _snake_case       ,      _snake_case       ,      _snake_case	)       ,      mf_knapsack(i - 1       ,      _snake_case       ,      _snake_case       ,      j - wt[i - 1]	) + val[i - 1]       ,      )
            lowerCAmelCase    :		Dict				=      val
      return f[i][j]


def    _snake_case  (  _snake_case :	Union[str, Any]       ,      _snake_case :	int       ,      _snake_case :	List[Any]       ,      _snake_case :	int	):
      lowerCAmelCase    :		Optional[int]				=      [[0] * (w + 1) for _ in range(n + 1	)]

      for i in range(1       ,      n + 1	):
            for w_ in range(1       ,      w + 1	):
                  if wt[i - 1] <= w_:
                        lowerCAmelCase    :		Union[str, Any]				=      max(val[i - 1] + dp[i - 1][w_ - wt[i - 1]]       ,      dp[i - 1][w_]	)
                  else:
                        lowerCAmelCase    :		Tuple				=      dp[i - 1][w_]

      return dp[n][w_], dp


def    _snake_case  (  _snake_case :	int       ,      _snake_case :	list       ,      _snake_case :	list	):
      if not (isinstance(_snake_case       ,      (list, tuple)	) and isinstance(_snake_case       ,      (list, tuple)	)):
            raise ValueError(
                '''Both the weights and values vectors must be either lists or tuples'''	)

      lowerCAmelCase    :		Any				=      len(_snake_case	)
      if num_items != len(_snake_case	):
            lowerCAmelCase    :		int				=      (
                '''The number of weights must be the same as the number of values.\n'''
                f'''But got {num_items} weights and {len(_snake_case	)} values'''
            )
            raise ValueError(_snake_case	)
      for i in range(_snake_case	):
            if not isinstance(wt[i]       ,      _snake_case	):
                  lowerCAmelCase    :		Any				=      (
                      '''All weights must be integers but got weight of '''
                      f'''type {type(wt[i]	)} at index {i}'''
                  )
                  raise TypeError(_snake_case	)

      lowerCAmelCase,					lowerCAmelCase    :		List[str]				=      knapsack(_snake_case       ,      _snake_case       ,      _snake_case       ,      _snake_case	)
      lowerCAmelCase    :		set				=      set()
      _construct_solution(_snake_case       ,      _snake_case       ,      _snake_case       ,      _snake_case       ,      _snake_case	)

      return optimal_val, example_optional_set


def    _snake_case  (  _snake_case :	list       ,      _snake_case :	list       ,      _snake_case :	int       ,      _snake_case :	int       ,      _snake_case :	set	):
      # for the current item i at a maximum weight j to be part of an optimal subset,
      # the optimal value at (i, j) must be greater than the optimal value at (i-1, j).
      # where i - 1 means considering only the previous items at the given maximum weight
      if i > 0 and j > 0:
            if dp[i - 1][j] == dp[i][j]:
                  _construct_solution(_snake_case       ,      _snake_case       ,      i - 1       ,      _snake_case       ,      _snake_case	)
            else:
                  optimal_set.add(_snake_case	)
                  _construct_solution(_snake_case       ,      _snake_case       ,      i - 1       ,      j - wt[i - 1]       ,      _snake_case	)


if __name__ == "__main__":
 snake_case__						:   Optional[int]			 = [3, 2, 4, 4]
 snake_case__						:   str			 = [4, 3, 2, 3]
 snake_case__						:   List[str]			 = 4
 snake_case__						:   Optional[Any]			 = 6
 snake_case__						:   Union[str, Any]			 = [[0] * (w + 1)] + [[0] + [-1] * (w + 1) for _ in range(n + 1)]
 snake_case__ ,   snake_case__						:   Any			 = knapsack(w, wt, val, n)
 print(optimal_solution)
 print(mf_knapsack(n, wt, val, w))  # switched the n and w

 # testing the dynamic programming problem with example
 # the optimal subset for the above example are items 3 and 4
 snake_case__ ,   snake_case__						:   int			 = knapsack_with_example_solution(w, wt, val)
 assert optimal_solution == 8
 assert optimal_subset == {3, 4}
 print('''optimal_value = ''', optimal_solution)
 print('''An optimal subset corresponding to the optimal value''', optimal_subset)






"""simple docstring"""





def    _snake_case  (  _snake_case :	int	):

      if not isinstance(_snake_case       ,      _snake_case	):
            raise TypeError('''only integers accepted as input'''	)
      else:
            lowerCAmelCase    :		List[str]				=      str(abs(_snake_case	)	)
            lowerCAmelCase    :		Optional[Any]				=      [list(_snake_case	) for char in range(len(_snake_case	)	)]
            for index in range(len(_snake_case	)	):
                  num_transpositions[index].pop(_snake_case	)
            return max(
                int(''''''.join(list(_snake_case	)	)	) for transposition in num_transpositions	)


if __name__ == "__main__":
 __import__('''doctest''').testmod()


