JSFiddle - React, Tailwind, and code Playground
JavaScript
const boxes = {
'a': { id: 'a', value: 15, weight: 85 },
'b': { id: 'b', value: 40, weight: 60 },
'c': { id: 'c', value: 60, weight: 40 },
'd': { id: 'd', value: 10, weight: 20 }
}
const VALUE_CONSTRAINT = 600
let candidates = new Map([[0, { value: 1, weight: 0, ids: ['identitybox'] }]])
const totalWeight = Object.values(boxes).reduce((s, x) => s + x.weight, 0)
let best = {
value: 1,
weight: totalWeight + 1
}
for (const box of Object.values(boxes)) {
const next = new Map([...candidates.entries()])
for (const candidate of candidates.values()) {
// warn, int overflow
const value = candidate.value * box.value
if (value > VALUE_CONSTRAINT) {
continue
}
const weight = candidate.weight + box.weight
if (!next.has(value) || weight < next.get(value).weight) {
const betterCandidate = { value, weight, ids: [box.id, ...candidate.ids] }
if (weight < best.weight && value === VALUE_CONSTRAINT) {
console.log('improve', { weight, betterCandidate })
best = betterCandidate
}
next.set(value, betterCandidate)
}
}
candidates = next
}