Skip to content

Commit f666df6

Browse files
authored
Knapsack (#765)
* add practice exercise knapsack * fixed typo in a comment
1 parent d1990b4 commit f666df6

File tree

8 files changed

+173
-0
lines changed

8 files changed

+173
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,14 @@
970970
"prerequisites": [],
971971
"difficulty": 5
972972
},
973+
{
974+
"slug": "knapsack",
975+
"name": "Knapsack",
976+
"uuid": "7c4ecd30-dbd0-489e-a68c-513e9ecb12d9",
977+
"practices": [],
978+
"prerequisites": [],
979+
"difficulty": 5
980+
},
973981
{
974982
"slug": "game-of-life",
975983
"name": "Conway's Game of Life",
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Instructions
2+
3+
Your task is to determine which items to take so that the total value of his selection is maximized, taking into account the knapsack's carrying capacity.
4+
5+
Items will be represented as a list of items.
6+
Each item will have a weight and value.
7+
All values given will be strictly positive.
8+
Bob can take only one of each item.
9+
10+
For example:
11+
12+
```text
13+
Items: [
14+
{ "weight": 5, "value": 10 },
15+
{ "weight": 4, "value": 40 },
16+
{ "weight": 6, "value": 30 },
17+
{ "weight": 4, "value": 50 }
18+
]
19+
20+
Knapsack Maximum Weight: 10
21+
```
22+
23+
For the above, the first item has weight 5 and value 10, the second item has weight 4 and value 40, and so on.
24+
In this example, Bob should take the second and fourth item to maximize his value, which, in this case, is 90.
25+
He cannot get more than 90 as his knapsack has a weight limit of 10.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Introduction
2+
3+
Bob is a thief.
4+
After months of careful planning, he finally manages to crack the security systems of a fancy store.
5+
6+
In front of him are many items, each with a value and weight.
7+
Bob would gladly take all of the items, but his knapsack can only hold so much weight.
8+
Bob has to carefully consider which items to take so that the total value of his selection is maximized.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"colinleach"
4+
],
5+
"files": {
6+
"solution": [
7+
"knapsack.jl"
8+
],
9+
"test": [
10+
"runtests.jl"
11+
],
12+
"example": [
13+
".meta/example.jl"
14+
]
15+
},
16+
"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.",
17+
"source": "Wikipedia",
18+
"source_url": "https://en.wikipedia.org/wiki/Knapsack_problem"
19+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
function maximum_value(maximum_weight, items)
2+
# See https://en.wikipedia.org/wiki/Knapsack_problem#Dynamic_programming_in-advance_algorithm
3+
4+
numitems = length(items)
5+
numitems == 0 && return 0
6+
7+
# Remember, Julia uses 1-based array indexing
8+
# so maxes[r,c] indexing needs to be r+1, c+1, compared to the Wiki reference
9+
10+
maxes = zeros(UInt16, numitems + 1, maximum_weight + 1)
11+
for item_count in 1:numitems
12+
for weight in 1:(maximum_weight)
13+
curr_weight = items[item_count].weight
14+
if curr_weight > weight
15+
# copy the row above, the new item is no use to us
16+
maxes[item_count + 1, weight + 1] = maxes[item_count, weight + 1]
17+
else
18+
# perhaps drop an old item, add the new one?
19+
replace_last = maxes[item_count, weight - curr_weight + 1] + items[item_count].value
20+
maxes[item_count + 1, weight + 1] = max(maxes[item_count, weight + 1], replace_last)
21+
end
22+
end
23+
end
24+
25+
# converting to signed int is not essential, but it can help with debugging
26+
Int(maxes[end, end])
27+
end
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
include = false
15+
16+
[3993a824-c20e-493d-b3c9-ee8a7753ee59]
17+
description = "no items"
18+
reimplements = "a4d7d2f0-ad8a-460c-86f3-88ba709d41a7"
19+
20+
[1d39e98c-6249-4a8b-912f-87cb12e506b0]
21+
description = "one item, too heavy"
22+
23+
[833ea310-6323-44f2-9d27-a278740ffbd8]
24+
description = "five items (cannot be greedy by weight)"
25+
26+
[277cdc52-f835-4c7d-872b-bff17bab2456]
27+
description = "five items (cannot be greedy by value)"
28+
29+
[81d8e679-442b-4f7a-8a59-7278083916c9]
30+
description = "example knapsack"
31+
32+
[f23a2449-d67c-4c26-bf3e-cde020f27ecc]
33+
description = "8 items"
34+
35+
[7c682ae9-c385-4241-a197-d2fa02c81a11]
36+
description = "15 items"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function maximum_value(maximum_weight, items)
2+
3+
end
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using Test
2+
3+
include("knapsack.jl")
4+
5+
struct Item
6+
weight
7+
value
8+
end
9+
10+
@testset verbose = true "tests" begin
11+
@testset "no items" begin
12+
@test maximum_value(100, []) == 0
13+
end
14+
15+
@testset "one item, too heavy" begin
16+
@test maximum_value(10, [Item(100, 1),]) == 0
17+
end
18+
19+
@testset "five items (cannot be greedy by weight)" begin
20+
items = [Item(2, 5), Item(2, 5), Item(2, 5), Item(2, 5), Item(10, 21)]
21+
@test maximum_value(10, items) == 21
22+
end
23+
24+
@testset "five items (cannot be greedy by value)" begin
25+
items = [Item(2, 20), Item(2, 20), Item(2, 20), Item(2, 20), Item(10, 50)]
26+
@test maximum_value(10, items) == 80
27+
end
28+
29+
@testset "example knapsack" begin
30+
items = [Item(5, 10), Item(4, 40), Item(6, 30), Item(4, 50)]
31+
@test maximum_value(10, items) == 90
32+
end
33+
34+
@testset "8 items" begin
35+
items = [Item(25, 350), Item(35, 400), Item(45, 450), Item(5, 20),
36+
Item(25, 70), Item(3, 8), Item(2, 5), Item(2, 5)]
37+
@test maximum_value(104, items) == 900
38+
end
39+
40+
@testset "15 items" begin
41+
items = [Item(70, 135), Item(73, 139), Item(77, 149), Item(80, 150),
42+
Item(82, 156), Item(87, 163), Item(90, 173), Item(94, 184),
43+
Item(98, 192), Item(106, 201), Item(110, 210), Item(113, 214),
44+
Item(115, 221), Item(118, 229), Item(120, 240)]
45+
@test maximum_value(750, items) == 1458
46+
end
47+
end

0 commit comments

Comments
 (0)