Q:

Algorithm to find the set of values which are repeatable to fit upto a maximum Total value

I have a set of values. (length of it can be dynamic. and some of the values can be undefined). Each of these values is an attack type.
Ex: attacks=[960,1200,1800,2120,undefined,undefined];
And a total value,
Ex: totalEnergy=18680;
Now I want a function to return an array of objects like,
Ex: 
[{
    attacks: [0,0,0,0,1,2],
    wastage: 128
    }, {
    attacks: [0,1,2,2,2],
    wastage: 298
    }, {
    attacks: [2,3,4],
    wastage: 593
}]

So here the attacks are possible attack combinations that can be done within the given energy limit and the remaining amount of energy wastage.
So the function will have a parameter called wastage that will mention the maximum amount of wastage that can be done.
The various types of attacks can be repeated as many number of times. but the total energy spent should be less than the total energy.
Ideally the number of higher level attacks is preferred like the attacks that cost more but that is upto the players decision. So I will just return all possible combos. The player has to choose the best bang for the buck.
I know this is some kind of Knapsack problem but I tried multiple solutions but nothing quite solves this problem.
I typically want this solution to be in javascript but any language is fine for demonstration purpose.
UPDATE:
Here is what I have got so far,
let totalEnergy = 3400;
let attacks = [980, 1220, 1680, 1920];
let attacksPossible = attacks.map((attack, iter) => {
    return Math.floor(totalEnergy/attack);
})
// Create an array which contains a repeatitive number of attacks possible
let attacksArray = attacks.map((attack, iter) => {
    return [...Array(attacksPossible[iter])].map(() => attack)
})
// Flatten 2D array into 1D array
attacksArray = [].concat.apply([], attacksArray);

console.log('attacksPossible', attacksPossible);
console.log('attacksArray', attacksArray);

Here I got a list of array which contains the maximum combination of attacks for the given total value, Now how do I proceed from here implementing knapsack over it?

A:

knapsack is not really relevant here as you want all choices. This is more similar to all ways of partitioning a set of numbers to sum n, with the exception that you can have a waste. The approach is the same with a slight modification:

let totalEnergy = 3400;
let attacks = [980, 1220, 1680, 1920];

let possibilities = [];
let current = [];

let minVal = Math.min.apply(null, attacks);
function solve (idx, left) {
  for (var i = idx; i < attacks.length;i++) {
    if (attacks[i] != undefined && attacks[i] <= left) {
      current.push(i);
      solve(i, left - attacks[i]);
      current.pop();
    }
  }
  
  if (left < minVal) {
    possibilities.push({attacks: current.slice(0), waste: left})
  } 
}

solve(0, totalEnergy);
console.log(possibilities);

