Skip to content

Commit 796f2ca

Browse files
authored
Add Knapsack exercise (#1661)
* Add knapsack exercise * Underscore unused params, turn string diff to int diff
1 parent 399488b commit 796f2ca

File tree

9 files changed

+360
-0
lines changed

9 files changed

+360
-0
lines changed

config.json

+8
Original file line numberDiff line numberDiff line change
@@ -1508,6 +1508,14 @@
15081508
],
15091509
"status": "deprecated"
15101510
},
1511+
{
1512+
"slug": "knapsack",
1513+
"name": "Knapsack",
1514+
"uuid": "cbccd0c5-eb15-4705-9a4c-0209861f078c",
1515+
"practices": [],
1516+
"prerequisites": [],
1517+
"difficulty": 4
1518+
},
15111519
{
15121520
"slug": "kindergarten-garden",
15131521
"name": "Kindergarten Garden",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Instructions
2+
3+
In this exercise, let's try to solve a classic problem.
4+
5+
Bob is a thief.
6+
After months of careful planning, he finally manages to crack the security systems of a high-class apartment.
7+
8+
In front of him are many items, each with a value (v) and weight (w).
9+
Bob, of course, wants to maximize the total value he can get; he would gladly take all of the items if he could.
10+
However, to his horror, he realizes that the knapsack he carries with him can only hold so much weight (W).
11+
12+
Given a knapsack with a specific carrying capacity (W), help Bob determine the maximum value he can get from the items in the house.
13+
Note that Bob can take only one of each item.
14+
15+
All values given will be strictly positive.
16+
Items will be represented as a list of pairs, `wi` and `vi`, where the first element `wi` is the weight of the *i*th item and `vi` is the value for that item.
17+
18+
For example:
19+
20+
Items: [
21+
{ "weight": 5, "value": 10 },
22+
{ "weight": 4, "value": 40 },
23+
{ "weight": 6, "value": 30 },
24+
{ "weight": 4, "value": 50 }
25+
]
26+
27+
Knapsack Limit: 10
28+
29+
For the above, the first item has weight 5 and value 10, the second item has weight 4 and value 40, and so on.
30+
31+
In this example, Bob should take the second and fourth item to maximize his value, which, in this case, is 90.
32+
He cannot get more than 90 as his knapsack has a weight limit of 10.
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Generated by Cargo
2+
# Will have compiled files and executables
3+
/target/
4+
**/*.rs.bk
5+
6+
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
7+
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
8+
Cargo.lock
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"authors": [
3+
"dem4ron"
4+
],
5+
"files": {
6+
"solution": [
7+
"src/lib.rs",
8+
"Cargo.toml"
9+
],
10+
"test": [
11+
"tests/knapsack.rs"
12+
],
13+
"example": [
14+
".meta/example.rs"
15+
]
16+
},
17+
"blurb": "Given a knapsack that can only carry a certain weight, determine which items to put in the knapsack in order to maximize their combined value.",
18+
"source": "Wikipedia",
19+
"source_url": "https://en.wikipedia.org/wiki/Knapsack_problem"
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
pub struct Item {
2+
pub weight: u32,
3+
pub value: u32,
4+
}
5+
6+
pub fn maximum_value(max_weight: u32, items: Vec<Item>) -> u32 {
7+
let mut max_values = vec![vec![0; (max_weight + 1) as usize]; items.len() + 1];
8+
9+
for i in 1..=items.len() {
10+
let item_weight = items[i - 1].weight as usize;
11+
let item_value = items[i - 1].value;
12+
13+
for w in 0..=(max_weight as usize) {
14+
if item_weight <= w {
15+
max_values[i][w] = std::cmp::max(
16+
max_values[i - 1][w],
17+
max_values[i - 1][w - item_weight] + item_value,
18+
);
19+
} else {
20+
max_values[i][w] = max_values[i - 1][w];
21+
}
22+
}
23+
}
24+
25+
max_values[items.len()][max_weight as usize]
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[a4d7d2f0-ad8a-460c-86f3-88ba709d41a7]
13+
description = "no items"
14+
15+
[1d39e98c-6249-4a8b-912f-87cb12e506b0]
16+
description = "one item, too heavy"
17+
18+
[833ea310-6323-44f2-9d27-a278740ffbd8]
19+
description = "five items (cannot be greedy by weight)"
20+
21+
[277cdc52-f835-4c7d-872b-bff17bab2456]
22+
description = "five items (cannot be greedy by value)"
23+
24+
[81d8e679-442b-4f7a-8a59-7278083916c9]
25+
description = "example knapsack"
26+
27+
[f23a2449-d67c-4c26-bf3e-cde020f27ecc]
28+
description = "8 items"
29+
30+
[7c682ae9-c385-4241-a197-d2fa02c81a11]
31+
description = "15 items"
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "knapsack"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
pub struct Item {
2+
pub weight: u32,
3+
pub value: u32,
4+
}
5+
6+
pub fn maximum_value(_max_weight: u32, _items: Vec<Item>) -> u32 {
7+
unimplemented!("Solve the knapsack exercise");
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
use knapsack::*;
2+
3+
#[test]
4+
fn test_example_knapsack() {
5+
let max_weight = 10;
6+
let items = vec![
7+
Item {
8+
weight: 5,
9+
value: 10,
10+
},
11+
Item {
12+
weight: 4,
13+
value: 40,
14+
},
15+
Item {
16+
weight: 6,
17+
value: 30,
18+
},
19+
Item {
20+
weight: 4,
21+
value: 50,
22+
},
23+
];
24+
25+
assert_eq!(maximum_value(max_weight, items), 90);
26+
}
27+
28+
#[test]
29+
#[ignore]
30+
fn test_no_items() {
31+
let max_weight = 100;
32+
let items = vec![];
33+
34+
assert_eq!(maximum_value(max_weight, items), 0);
35+
}
36+
37+
#[test]
38+
#[ignore]
39+
fn test_one_item_too_heavy() {
40+
let max_weight = 10;
41+
let items = vec![Item {
42+
weight: 100,
43+
value: 1,
44+
}];
45+
46+
assert_eq!(maximum_value(max_weight, items), 0);
47+
}
48+
49+
#[test]
50+
#[ignore]
51+
fn test_five_items_cannot_be_greedy_by_weight() {
52+
let max_weight = 10;
53+
let items = vec![
54+
Item {
55+
weight: 2,
56+
value: 5,
57+
},
58+
Item {
59+
weight: 2,
60+
value: 5,
61+
},
62+
Item {
63+
weight: 2,
64+
value: 5,
65+
},
66+
Item {
67+
weight: 2,
68+
value: 5,
69+
},
70+
Item {
71+
weight: 10,
72+
value: 21,
73+
},
74+
];
75+
76+
assert_eq!(maximum_value(max_weight, items), 21);
77+
}
78+
79+
#[test]
80+
#[ignore]
81+
fn test_five_items_cannot_be_greedy_by_value() {
82+
let max_weight = 10;
83+
let items = vec![
84+
Item {
85+
weight: 2,
86+
value: 20,
87+
},
88+
Item {
89+
weight: 2,
90+
value: 20,
91+
},
92+
Item {
93+
weight: 2,
94+
value: 20,
95+
},
96+
Item {
97+
weight: 2,
98+
value: 20,
99+
},
100+
Item {
101+
weight: 10,
102+
value: 50,
103+
},
104+
];
105+
106+
assert_eq!(maximum_value(max_weight, items), 80);
107+
}
108+
109+
#[test]
110+
#[ignore]
111+
fn test_8_items() {
112+
let max_weight = 104;
113+
let items = vec![
114+
Item {
115+
weight: 25,
116+
value: 350,
117+
},
118+
Item {
119+
weight: 35,
120+
value: 400,
121+
},
122+
Item {
123+
weight: 45,
124+
value: 450,
125+
},
126+
Item {
127+
weight: 5,
128+
value: 20,
129+
},
130+
Item {
131+
weight: 25,
132+
value: 70,
133+
},
134+
Item {
135+
weight: 3,
136+
value: 8,
137+
},
138+
Item {
139+
weight: 2,
140+
value: 5,
141+
},
142+
Item {
143+
weight: 2,
144+
value: 5,
145+
},
146+
];
147+
148+
assert_eq!(maximum_value(max_weight, items), 900);
149+
}
150+
151+
#[test]
152+
#[ignore]
153+
fn test_15_items() {
154+
let max_weight = 750;
155+
let items = vec![
156+
Item {
157+
weight: 70,
158+
value: 135,
159+
},
160+
Item {
161+
weight: 73,
162+
value: 139,
163+
},
164+
Item {
165+
weight: 77,
166+
value: 149,
167+
},
168+
Item {
169+
weight: 80,
170+
value: 150,
171+
},
172+
Item {
173+
weight: 82,
174+
value: 156,
175+
},
176+
Item {
177+
weight: 87,
178+
value: 163,
179+
},
180+
Item {
181+
weight: 90,
182+
value: 173,
183+
},
184+
Item {
185+
weight: 94,
186+
value: 184,
187+
},
188+
Item {
189+
weight: 98,
190+
value: 192,
191+
},
192+
Item {
193+
weight: 106,
194+
value: 201,
195+
},
196+
Item {
197+
weight: 110,
198+
value: 210,
199+
},
200+
Item {
201+
weight: 113,
202+
value: 214,
203+
},
204+
Item {
205+
weight: 115,
206+
value: 221,
207+
},
208+
Item {
209+
weight: 118,
210+
value: 229,
211+
},
212+
Item {
213+
weight: 120,
214+
value: 240,
215+
},
216+
];
217+
218+
assert_eq!(maximum_value(max_weight, items), 1458);
219+
}

0 commit comments

Comments
 (0)