Repository: TheAlgorithms/C-Plus-Plus
File: dynamic_programming/Unbounded_0_1_Knapsack.cpp (C++)

Code before:
/**
 * @brief Wrapper function to initiate the unbounded knapsack calculation.
 *
 * @param N Number of items.
 * @param W Maximum weight capacity of the knapsack.
 * @param val Vector of values corresponding to the items.
 * @param wt Vector of weights corresponding to the items.
 * @return The maximum value that can be obtained for the given capacity.
 */
int unboundedKnapsack(std::uint16_t N, std::uint16_t W, 
                      const std::vector<std::uint16_t>& val, 
                      const std::vector<std::uint16_t>& wt) {
    if(N==0)return 0; // Expect 0 since no items
    std::vector<std::vector<int>> dp(N, std::vector<int>(W + 1, -1)); // Initialize memoization table
    return KnapSackFilling(N - 1, W, val, wt, dp); // Start the calculation
}

} // unbounded_knapsack

} // dynamic_programming

/**
 * @brief Function to run test cases for the unbounded knapsack implementation.
 * 
 * @details This function tests the implementation with predefined test cases.
 * It asserts the expected outcomes to ensure correctness of the algorithm.
 */
static void tests() {
    // Test Case 1
    std::uint16_t N1 = 4;  // Number of items
    std::vector<std::uint16_t> wt1 = {1, 3, 4, 5}; // Weights of the items
    std::vector<std::uint16_t> val1 = {6, 1, 7, 7}; // Values of the items
    std::uint16_t W1 = 8; // Maximum capacity of the knapsack
    // Test the function and assert the expected output
    assert(unboundedKnapsack(N1, W1, val1, wt1) == 48);
    std::cout << "Maximum Knapsack value " << unboundedKnapsack(N1, W1, val1, wt1) << std::endl;

    // Test Case 2
    std::uint16_t N2 = 3; // Number of items
    std::vector<std::uint16_t> wt2 = {10, 20, 30}; // Weights of the items
    std::vector<std::uint16_t> val2 = {60, 100, 120}; // Values of the items
    std::uint16_t W2 = 5; // Maximum capacity of the knapsack
    // Test the function and assert the expected output
    assert(unboundedKnapsack(N2, W2, val2, wt2) == 0);
    std::cout << "Maximum Knapsack value " << unboundedKnapsack(N2, W2, val2, wt2) << std::endl;

    // Test Case 3
    std::uint16_t N3 = 3; // Number of items
    std::vector<std::uint16_t> wt3 = {2, 4, 6}; // Weights of the items
    std::vector<std::uint16_t> val3 = {5, 11, 13};// Values of the items 
    std::uint16_t W3 = 27;// Maximum capacity of the knapsack 

Review comment (suggestion):
```suggestion
 * @brief self test implementation
 * @return void
```

Code after:
/**
 * @brief Wrapper function to initiate the unbounded knapsack calculation.
 *
 * @param N Number of items.
 * @param W Maximum weight capacity of the knapsack.
 * @param val Vector of values corresponding to the items.
 * @param wt Vector of weights corresponding to the items.
 * @return The maximum value that can be obtained for the given capacity.
 */
std::uint16_t unboundedKnapsack(std::uint16_t N, std::uint16_t W, 
                      const std::vector<std::uint16_t>& val, 
                      const std::vector<std::uint16_t>& wt) {
    if(N==0)return 0; // Expect 0 since no items
    std::vector<std::vector<int>> dp(N, std::vector<int>(W + 1, -1)); // Initialize memoization table
    return KnapSackFilling(N - 1, W, val, wt, dp); // Start the calculation
}

} // unbounded_knapsack

} // dynamic_programming

/**
 * @brief self test implementation
 * @return void
 */
static void tests() {
    // Test Case 1
    std::uint16_t N1 = 4;  // Number of items
    std::vector<std::uint16_t> wt1 = {1, 3, 4, 5}; // Weights of the items
    std::vector<std::uint16_t> val1 = {6, 1, 7, 7}; // Values of the items
    std::uint16_t W1 = 8; // Maximum capacity of the knapsack
    // Test the function and assert the expected output
    assert(unboundedKnapsack(N1, W1, val1, wt1) == 48);
    std::cout << "Maximum Knapsack value " << unboundedKnapsack(N1, W1, val1, wt1) << std::endl;

    // Test Case 2
    std::uint16_t N2 = 3; // Number of items
    std::vector<std::uint16_t> wt2 = {10, 20, 30}; // Weights of the items
    std::vector<std::uint16_t> val2 = {60, 100, 120}; // Values of the items
    std::uint16_t W2 = 5; // Maximum capacity of the knapsack
    // Test the function and assert the expected output
    assert(unboundedKnapsack(N2, W2, val2, wt2) == 0);
    std::cout << "Maximum Knapsack value " << unboundedKnapsack(N2, W2, val2, wt2) << std::endl;

    // Test Case 3
    std::uint16_t N3 = 3; // Number of items
    std::vector<std::uint16_t> wt3 = {2, 4, 6}; // Weights of the items
    std::vector<std::uint16_t> val3 = {5, 11, 13};// Values of the items 
    std::uint16_t W3 = 27;// Maximum capacity of the knapsack 
    // Test the function and assert the expected output
    assert(unboundedKnapsack(N3, W3, val3, wt3) == 27);