Skip to content

Commit c43e8d6

Browse files
Add knapsack exercise
1 parent ca61b89 commit c43e8d6

File tree

12 files changed

+1074
-0
lines changed

12 files changed

+1074
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,14 @@
516516
"prerequisites": [],
517517
"difficulty": 5
518518
},
519+
{
520+
"slug": "knapsack",
521+
"name": "Knapsack",
522+
"uuid": "3a56fade-68b2-4f6a-bb73-d13c4af3aa68",
523+
"practices": [],
524+
"prerequisites": [],
525+
"difficulty": 5
526+
},
519527
{
520528
"slug": "largest-series-product",
521529
"name": "Largest Series Product",
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 her 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+
Lhakpa 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, Lhakpa should take the second and fourth item to maximize her value, which, in this case, is 90.
25+
She cannot get more than 90 as her knapsack has a weight limit of 10.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Introduction
2+
3+
Lhakpa is a [Sherpa][sherpa] mountain guide and porter.
4+
After months of careful planning, the expedition Lhakpa works for is about to leave.
5+
She will be paid the value she carried to the base camp.
6+
7+
In front of her are many items, each with a value and weight.
8+
Lhakpa would gladly take all of the items, but her knapsack can only hold so much weight.
9+
10+
[sherpa]: https://en.wikipedia.org/wiki/Sherpa_people#Mountaineering
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"keiravillekode"
4+
],
5+
"files": {
6+
"solution": [
7+
"Knapsack.pas"
8+
],
9+
"test": [
10+
"TestCases.pas"
11+
],
12+
"example": [
13+
".meta/example.pas"
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: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
unit Knapsack;
2+
3+
{$mode ObjFPC}{$H+}
4+
5+
interface
6+
7+
type
8+
TItem = record
9+
weight: Integer;
10+
value: Integer;
11+
end;
12+
13+
TItemArray = Array Of TItem;
14+
TIntArray = Array Of Integer;
15+
16+
function maximumValue(const maximumWeight : Integer; const items : TItemArray) : Integer;
17+
18+
implementation
19+
20+
uses SysUtils;
21+
22+
function maximumValue(const maximumWeight : Integer; const items : TItemArray) : Integer;
23+
var
24+
table : TIntArray = ();
25+
itemIndex : Integer;
26+
index : Integer;
27+
value : Integer;
28+
begin
29+
SetLength(table, maximumWeight + 1);
30+
for index := Low(table) to High(table) do
31+
table[index] := 0;
32+
33+
for itemIndex := Low(items) to High(items) do
34+
begin
35+
index := maximumWeight + 1;
36+
while index > items[itemIndex].weight do
37+
begin
38+
index := index - 1;
39+
value := items[itemIndex].value + table[index - items[itemIndex].weight];
40+
if table[index] < value then
41+
table[index] := value;
42+
end;
43+
end;
44+
45+
result := table[maximumWeight];
46+
end;
47+
48+
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: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
unit Knapsack;
2+
3+
{$mode ObjFPC}{$H+}
4+
5+
interface
6+
7+
type
8+
TItem = record
9+
weight: Integer;
10+
value: Integer;
11+
end;
12+
13+
TItemArray = Array Of TItem;
14+
15+
function maximumValue(const maximumWeight : Integer; const items : TItemArray) : Integer;
16+
17+
implementation
18+
19+
uses SysUtils;
20+
21+
function maximumValue(const maximumWeight : Integer; const items : TItemArray) : Integer;
22+
begin
23+
24+
raise ENotImplemented.Create('Please implement your solution.'); result := maximumWeight + length(items);
25+
26+
end;
27+
28+
end.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
SHELL = /bin/bash
2+
MAKEFLAGS += --no-print-directory
3+
DESTDIR = build
4+
EXECUTABLE = $(DESTDIR)/test
5+
COMMAND = fpc -l- -v0 -g -gl -Sa -Cr -Sehnw -Fu./lib test.pas -FE"./$(DESTDIR)"
6+
7+
.ONESHELL:
8+
9+
test:
10+
@mkdir -p "./$(DESTDIR)"
11+
@cp -r ./lib "./$(DESTDIR)"
12+
@$(COMMAND) && ./$(EXECUTABLE) $(test)
13+
14+
clean:
15+
@rm -fr "./$(DESTDIR)"
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
unit TestCases;
2+
3+
{$mode ObjFPC}{$H+}
4+
5+
interface
6+
7+
uses Classes, SysUtils, FPCUnit, TestRegistry, FPCUnitTestUtils;
8+
9+
type
10+
KnapsackTest = class(TTestCase)
11+
published
12+
procedure no_items;
13+
procedure one_item_too_heavy;
14+
procedure five_items_cannot_be_greedy_by_weight;
15+
procedure five_items_cannot_be_greedy_by_value;
16+
procedure example_knapsack;
17+
procedure _8_items;
18+
procedure _15_items;
19+
end;
20+
21+
implementation
22+
23+
uses Knapsack;
24+
25+
// 3993a824-c20e-493d-b3c9-ee8a7753ee59
26+
procedure KnapsackTest.no_items;
27+
const
28+
items : TItemArray = (
29+
);
30+
begin
31+
TapAssertTrue(Self, 'no items', 0, Knapsack.maximumValue(100, items));
32+
end;
33+
34+
// 1d39e98c-6249-4a8b-912f-87cb12e506b0
35+
procedure KnapsackTest.one_item_too_heavy;
36+
const
37+
items : TItemArray = (
38+
(weight: 100; value: 1)
39+
);
40+
begin
41+
TapAssertTrue(Self, 'one item, too heavy', 0, Knapsack.maximumValue(10, items));
42+
end;
43+
44+
// 833ea310-6323-44f2-9d27-a278740ffbd8
45+
procedure KnapsackTest.five_items_cannot_be_greedy_by_weight;
46+
const
47+
items : TItemArray = (
48+
(weight: 2; value: 5),
49+
(weight: 2; value: 5),
50+
(weight: 2; value: 5),
51+
(weight: 2; value: 5),
52+
(weight: 10; value: 21)
53+
);
54+
begin
55+
TapAssertTrue(Self, 'five items (cannot be greedy by weight)', 21, Knapsack.maximumValue(10, items));
56+
end;
57+
58+
// 277cdc52-f835-4c7d-872b-bff17bab2456
59+
procedure KnapsackTest.five_items_cannot_be_greedy_by_value;
60+
const
61+
items : TItemArray = (
62+
(weight: 2; value: 20),
63+
(weight: 2; value: 20),
64+
(weight: 2; value: 20),
65+
(weight: 2; value: 20),
66+
(weight: 10; value: 50)
67+
);
68+
begin
69+
TapAssertTrue(Self, 'five items (cannot be greedy by value)', 80, Knapsack.maximumValue(10, items));
70+
end;
71+
72+
// 81d8e679-442b-4f7a-8a59-7278083916c9
73+
procedure KnapsackTest.example_knapsack;
74+
const
75+
items : TItemArray = (
76+
(weight: 5; value: 10),
77+
(weight: 4; value: 40),
78+
(weight: 6; value: 30),
79+
(weight: 4; value: 50)
80+
);
81+
begin
82+
TapAssertTrue(Self, 'example knapsack', 90, Knapsack.maximumValue(10, items));
83+
end;
84+
85+
// f23a2449-d67c-4c26-bf3e-cde020f27ecc
86+
procedure KnapsackTest._8_items;
87+
const
88+
items : TItemArray = (
89+
(weight: 25; value: 350),
90+
(weight: 35; value: 400),
91+
(weight: 45; value: 450),
92+
(weight: 5; value: 20),
93+
(weight: 25; value: 70),
94+
(weight: 3; value: 8),
95+
(weight: 2; value: 5),
96+
(weight: 2; value: 5)
97+
);
98+
begin
99+
TapAssertTrue(Self, '8 items', 900, Knapsack.maximumValue(104, items));
100+
end;
101+
102+
// 7c682ae9-c385-4241-a197-d2fa02c81a11
103+
procedure KnapsackTest._15_items;
104+
const
105+
items : TItemArray = (
106+
(weight: 70; value: 135),
107+
(weight: 73; value: 139),
108+
(weight: 77; value: 149),
109+
(weight: 80; value: 150),
110+
(weight: 82; value: 156),
111+
(weight: 87; value: 163),
112+
(weight: 90; value: 173),
113+
(weight: 94; value: 184),
114+
(weight: 98; value: 192),
115+
(weight: 106; value: 201),
116+
(weight: 110; value: 210),
117+
(weight: 113; value: 214),
118+
(weight: 115; value: 221),
119+
(weight: 118; value: 229),
120+
(weight: 120; value: 240)
121+
);
122+
begin
123+
TapAssertTrue(Self, '15 items', 1458, Knapsack.maximumValue(750, items));
124+
end;
125+
126+
initialization
127+
RegisterTest(KnapsackTest);
128+
129+
end.

0 commit comments

Comments
 (0)