Skip to content

Commit fbc4eba

Browse files
authored
Add knapsack exercise (#525)
1 parent 5679258 commit fbc4eba

File tree

15 files changed

+268
-0
lines changed

15 files changed

+268
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,14 @@
549549
"practices": [],
550550
"prerequisites": [],
551551
"difficulty": 2
552+
},
553+
{
554+
"slug": "knapsack",
555+
"name": "Knapsack",
556+
"uuid": "c3bd5203-459c-4ea8-9b20-f4f5099808d8",
557+
"practices": [],
558+
"prerequisites": [],
559+
"difficulty": 4
552560
}
553561
]
554562
},
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+
"kahgoh"
4+
],
5+
"files": {
6+
"solution": [
7+
"knapsack.ml"
8+
],
9+
"test": [
10+
"test.ml"
11+
],
12+
"example": [
13+
".meta/example.ml"
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: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
type item = {
2+
weight : int;
3+
value : int;
4+
}
5+
6+
let max_value (i: item) (prev_values: int list) (capacity: int): int =
7+
let value_without = List.nth prev_values capacity in
8+
match (i.weight, capacity) with
9+
| (w, c) when c < w -> value_without
10+
| (w, c) -> let value_with = (List.nth prev_values (c - w)) + i.value in
11+
Int.max value_with value_without
12+
13+
let next_values (i: item) (prev_values: int list): int list =
14+
List.mapi (fun capacity _v -> max_value i prev_values capacity) prev_values
15+
16+
let rec calculate_values (items: item list) (values: int list): int list =
17+
match items with
18+
| [] -> values
19+
| i :: next -> calculate_values next (next_values i values)
20+
21+
let rec last_value (v: int) (l: int list): int =
22+
match l with
23+
| [] -> v
24+
| n :: r -> last_value n r
25+
26+
let maximum_value (items: item list) (capacity: int): int =
27+
let size = capacity + 1 in
28+
let initial = List.init size (fun (_) -> 0) in
29+
calculate_values items initial
30+
|> last_value 0
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"

exercises/practice/knapsack/Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
default: clean test
2+
3+
test:
4+
dune runtest
5+
6+
clean:
7+
dune clean
8+
9+
.PHONY: clean

exercises/practice/knapsack/dune

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
(executable
2+
(name test)
3+
(libraries base ounit2))
4+
5+
(alias
6+
(name runtest)
7+
(deps (:x test.exe))
8+
(action (run %{x})))
9+
10+
(alias
11+
(name buildtest)
12+
(deps (:x test.exe)))
13+
14+
(env
15+
(dev
16+
(flags (:standard -warn-error -A))))
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
(lang dune 1.1)
2+
(version 1.0)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
type item = {
2+
weight : int;
3+
value : int;
4+
}
5+
6+
let maximum_value (items: item list) (capacity: int): int =
7+
failwith "Please implement 'maximum_value'"

0 commit comments

Comments
 (0)