Files
freeCodeCamp/curriculum/challenges/ukrainian/22-rosetta-code/rosetta-code-challenges/knapsack-problem-unbounded.md
2024-01-24 19:52:36 +01:00

186 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: 5a23c84252665b21eecc7ed4
title: Задача пакування рюкзака/Необмежена
challengeType: 1
forumTopicId: 323655
dashedName: knapsack-problemunbounded
---
# --description--
A traveler gets diverted and has to make an unscheduled stop in what turns out to be Shangri-La. Opting to leave, he is allowed to take as much as he likes of the items available there, so long as it will fit in his knapsack, and he can carry it.
Він знає максимальну вагу, яку зможе нести; і, що об'єм рюкзака обмежений.
Над штрих-кодами предметів написана їх вага та об'єм. Він витягує свою останню копію фінансового звіту та дізнається ціну кожного предмету.
Йому можна брати лише цілі предмети, і їх є набагато більше, ніж він би зміг нести.
# --instructions--
Напишіть функцію, а у її параметрах вкажіть масив об'єктів, максимальну вагу та максимальний об'єм. Кожен об'єкт має назву, вартість, вагу та об'єм. Функція має повернути максимальне значення предметів, які мандрівник може взяти з собою.
# --hints--
`knapsackUnbounded([{ name:"panacea", value:3000, weight:0.3, volume:0.025 }, { name:"ichor", value:1800, weight:0.2, volume:0.015 }, { name:"gold", value:2500, weight:2, volume:0.002 }], 25, 0.25)` має повертати `54500`.
```js
assert.equal(
knapsackUnbounded(
[
{ name: 'panacea', value: 3000, weight: 0.3, volume: 0.025 },
{ name: 'ichor', value: 1800, weight: 0.2, volume: 0.015 },
{ name: 'gold', value: 2500, weight: 2, volume: 0.002 }
],
25,
0.25
),
54500
);
```
`knapsackUnbounded([{ name:"panacea", value:3000, weight:0.3, volume:0.025 }, { name:"ichor", value:1800, weight:0.2, volume:0.015 }, { name:"gold", value:2500, weight:2, volume:0.002 }], 55, 0.25)` має повертати `88400`.
```js
assert.equal(
knapsackUnbounded(
[
{ name: 'panacea', value: 3000, weight: 0.3, volume: 0.025 },
{ name: 'ichor', value: 1800, weight: 0.2, volume: 0.015 },
{ name: 'gold', value: 2500, weight: 2, volume: 0.002 }
],
55,
0.25
),
88400
);
```
`knapsackUnbounded([{ name:"panacea", value:3000, weight:0.3, volume:0.025 }, { name:"ichor", value:1800, weight:0.2, volume:0.015 }, { name:"gold", value:2500, weight:2, volume:0.002 }], 25, 0.15)` має повертати `42500`.
```js
assert.equal(
knapsackUnbounded(
[
{ name: 'panacea', value: 3000, weight: 0.3, volume: 0.025 },
{ name: 'ichor', value: 1800, weight: 0.2, volume: 0.015 },
{ name: 'gold', value: 2500, weight: 2, volume: 0.002 }
],
25,
0.15
),
42500
);
```
`knapsackUnbounded([{ name:"panacea", value:3000, weight:0.3, volume:0.025 }, { name:"ichor", value:1800, weight:0.2, volume:0.015 }, { name:"gold", value:2500, weight:2, volume:0.002 }], 35, 0.35)` має повертати `75900`.
```js
assert.equal(
knapsackUnbounded(
[
{ name: 'panacea', value: 3000, weight: 0.3, volume: 0.025 },
{ name: 'ichor', value: 1800, weight: 0.2, volume: 0.015 },
{ name: 'gold', value: 2500, weight: 2, volume: 0.002 }
],
35,
0.35
),
75900
);
```
`knapsackUnbounded([{ name:"panacea", value:3000, weight:0.3, volume:0.025 }, { name:"ichor", value:1800, weight:0.2, volume:0.015 }, { name:"gold", value:2500, weight:2, volume:0.002 }], 15, 0.25)` має повертати`43200`.
```js
assert.equal(
knapsackUnbounded(
[
{ name: 'panacea', value: 3000, weight: 0.3, volume: 0.025 },
{ name: 'ichor', value: 1800, weight: 0.2, volume: 0.015 },
{ name: 'gold', value: 2500, weight: 2, volume: 0.002 }
],
15,
0.25
),
43200
);
```
# --seed--
## --seed-contents--
```js
function knapsackUnbounded(items, maxweight, maxvolume) {
}
```
# --solutions--
```js
function knapsackUnbounded(items, maxWeight, maxVolume) {
function getPickTotals(items, pick) {
let totalValue = 0;
let totalWeight = 0;
let totalVolume = 0;
for (let i = 0; i < items.length; i++) {
totalValue += pick[i] * items[i].value;
totalWeight += pick[i] * items[i].weight;
totalVolume += pick[i] * items[i].volume;
}
return [totalValue, totalWeight, totalVolume];
}
function getMaxes(items, maxWeight, maxVolume) {
const maxes = [];
for (let i = 0; i < items.length; i++) {
const maxUnitsInWeight = Math.floor(maxWeight / items[i].weight);
const maxUnitsInVolume = Math.floor(maxVolume / items[i].volume);
const maxUnitsInLimit = Math.min(maxUnitsInWeight, maxUnitsInVolume);
maxes.push(maxUnitsInLimit);
}
return maxes;
}
function isInLimit(value, limit) {
return value <= limit;
}
function getCombinations(maxValues, curPicks, combinations) {
if (maxValues.length === 0) {
combinations.push(curPicks);
}
const curMax = maxValues[0];
const leftMaxValues = maxValues.slice(1);
for (let i = 0; i <= curMax; i++) {
getCombinations(leftMaxValues, curPicks.concat(i), combinations);
}
return combinations;
}
let bestValue = 0;
let bestPick = [];
const maxes = getMaxes(items, maxWeight, maxVolume);
const combinations = getCombinations(maxes, [], []);
for (let i = 0; i < combinations.length; i++) {
const curPick = combinations[i];
const [curValue, curWeight, curVolume] = getPickTotals(items, curPick);
if (!isInLimit(curWeight, maxWeight) || !isInLimit(curVolume, maxVolume)) {
continue;
}
if (curValue > bestValue) {
bestValue = curValue;
bestPick = [curPick];
} else if (curValue === bestValue) {
bestPick.push(curPick);
}
}
return bestValue;
}
```