Skip to content

Commit d5d1e32

Browse files
committed
naive cake thief
1 parent e4644a0 commit d5d1e32

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed

cake_thief.py

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
"""
2+
Write a function max_duffel_bag_value() that takes a list of cake type tuples and a weight capacity, and returns the maximum monetary value the duffel bag can hold.
3+
cake_tuples = [(7, 160), (3, 90), (2, 15)]
4+
capacity = 20
5+
6+
# Returns 555 (6 of the middle type of cake and 1 of the last type of cake)
7+
max_duffel_bag_value(cake_tuples, capacity)
8+
"""
9+
import unittest
10+
11+
12+
def find_best_value_cake(cake_tuples, max_capacity):
13+
best_value_cake = None
14+
best_ratio = None
15+
16+
for cake in cake_tuples:
17+
if cake[0] > max_capacity:
18+
continue
19+
20+
if cake[1] == 0:
21+
# don't consider cakes without value
22+
continue
23+
cake_ratio_value = float(cake[1] / cake[0])
24+
25+
if best_value_cake is None:
26+
best_value_cake = cake
27+
best_ratio = cake_ratio_value
28+
elif cake_ratio_value > best_ratio:
29+
best_value_cake = cake
30+
best_ratio = cake_ratio_value
31+
elif cake_ratio_value == best_ratio and max_capacity % cake[0] == 0:
32+
# only replace the cake if it's lighter (so we can fit more cakes!)
33+
best_value_cake = cake
34+
best_ratio = cake_ratio_value
35+
36+
return best_value_cake
37+
38+
39+
def max_duffel_bag_value(cake_tuples, capacity):
40+
""" time complexity: n + cn where n is the number of cakes and c is capacity
41+
space complexity: 1
42+
"""
43+
status = {
44+
'total_value': 0,
45+
'capacity': capacity
46+
}
47+
48+
if capacity == 0:
49+
return 0
50+
51+
while True:
52+
cake = find_best_value_cake(cake_tuples, status['capacity'])
53+
if not cake:
54+
return status['total_value']
55+
56+
if cake[0] <= status['capacity']:
57+
status['total_value'] += cake[1]
58+
status['capacity'] -= cake[0]
59+
60+
61+
class Test(unittest.TestCase):
62+
def test_base_case(self):
63+
actual = max_duffel_bag_value([(7, 160), (3, 90), (2, 15)], 20)
64+
expected = 555
65+
self.assertEqual(actual, expected)
66+
67+
def test_one_cake(self):
68+
actual = max_duffel_bag_value([(2, 1)], 9)
69+
expected = 4
70+
self.assertEqual(actual, expected)
71+
72+
def test_two_cakes(self):
73+
actual = max_duffel_bag_value([(4, 4), (5, 5)], 9)
74+
expected = 9
75+
self.assertEqual(actual, expected)
76+
77+
def test_two_cakes_ten(self):
78+
actual = max_duffel_bag_value([(4, 4), (5, 5)], 10)
79+
expected = 10
80+
self.assertEqual(actual, expected)
81+
82+
def test_only_take_less_valuable_cake(self):
83+
actual = max_duffel_bag_value([(4, 4), (5, 5)], 12)
84+
expected = 12
85+
self.assertEqual(actual, expected)
86+
87+
def test_lots_of_cakes(self):
88+
actual = max_duffel_bag_value([(2, 3), (3, 6), (5, 1), (6, 1), (7, 1), (8, 1)], 7)
89+
expected = 12
90+
self.assertEqual(actual, expected)
91+
92+
def test_value_to_weight_ratio_is_not_optimal(self):
93+
actual = max_duffel_bag_value([(51, 52), (50, 50)], 100)
94+
expected = 100
95+
self.assertEqual(actual, expected)
96+
97+
def test_zero_capacity(self):
98+
actual = max_duffel_bag_value([(1, 2)], 0)
99+
expected = 0
100+
self.assertEqual(actual, expected)
101+
102+
def test_cake_with_zero_value_and_weight(self):
103+
actual = max_duffel_bag_value([(0, 0), (2, 1)], 7)
104+
expected = 3
105+
self.assertEqual(actual, expected)
106+
107+
108+
unittest.main(verbosity=2)

0 commit comments

Comments
 (0)