Last active 1 day ago

cakeThief.js Raw
1class Bag {
2 constructor (capacity) {
3 this.capacity = capacity;
4 this.cakes = [];
5 this.weight = 0;
6 this.value = 0;
7 }
8
9 addCake (cake) {
10 this.cakes.push(cake);
11 this.value += cake.value;
12 this.weight += cake.weight;
13 }
14
15 getCapacityRemaining () {
16 return this.capacity - this.getWeight();
17 }
18
19 getValue () {
20 return this.value;
21 }
22
23 getWeight () {
24 return this.weight;
25 }
26}
27
28let cakeTypes = [
29 {weight: 7, value: 160},
30 {weight: 3, value: 90},
31 {weight: 1, value: 15}
32];
33
34// maxDuffelBagValue(cakeTypes, 20);
35
36function maxDuffelBagValue (cakeTypes, capacity) {
37 let bag = new Bag(capacity),
38 // clean our cake types to cover out of bounds values
39 validCakeTypes = cleanCakeTypes(cakeTypes),
40 // figure out what the smallest cake is
41 smallestCake = getSmallestCakeType(validCakeTypes);
42
43 // until we don't have enough weight left, find the most valuable cake
44 for (var capacityLeft = capacity; capacityLeft >= smallestCake.weight; capacityLeft = bag.getCapacityRemaining()) {
45 // reduce our cakeTypes to the index of the highest value density that can fit
46 let bestCake = validCakeTypes.reduce((prev, next) => {
47 // make sure this next cake will fit
48 if (next.weight <= capacityLeft) {
49 // decide which is higher value-weight ratio
50 return prev.value / prev.weight > next.value / next.weight ? prev : next;
51 }
52 // this next cake doesn't fit, keep the previous
53 else return prev;
54 }, {value: 0, weight: 1});
55
56 // add the cake to our bag (adding to its weight and value)
57 bag.addCake(bestCake);
58 }
59
60 return bag.getValue();
61}
62
63/**
64 * reduce our cakeType collection down to one with the lowest weight
65 * @param {array} cakeTypes - collection of cakeType object {weight, value}
66 * @return {object} cakeType
67*/
68function getSmallestCakeType (cakeTypes) {
69 return cakeTypes.reduce((prev, next) => prev.weight < next.weight ? prev : next);
70}
71
72/**
73 * cleanCakeTypes - filters out invalid cakeTypes
74 * @param {array} cakeTypes - collection of cakeType object {weight, value}
75 * @return {array} filtered collection of cakeType objects
76 */
77function cleanCakeTypes (cakeTypes) {
78 // filter out any cake types with weight or value of 0, that's unreal!
79 return cakeTypes.filter((type) => type.weight > 0 && type.value > 0);
80}