Skip to content

Commit 4ab0f88

Browse files
Add sieve exercise (#61)
1 parent 11b00be commit 4ab0f88

File tree

12 files changed

+1085
-0
lines changed

12 files changed

+1085
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,14 @@
396396
"prerequisites": [],
397397
"difficulty": 3
398398
},
399+
{
400+
"slug": "sieve",
401+
"name": "Sieve",
402+
"uuid": "b99f0eb0-269c-4f3c-9e40-2da54112dbae",
403+
"practices": [],
404+
"prerequisites": [],
405+
"difficulty": 3
406+
},
399407
{
400408
"slug": "space-age",
401409
"name": "Space Age",
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Instructions
2+
3+
Your task is to create a program that implements the Sieve of Eratosthenes algorithm to find all prime numbers less than or equal to a given number.
4+
5+
A prime number is a number larger than 1 that is only divisible by 1 and itself.
6+
For example, 2, 3, 5, 7, 11, and 13 are prime numbers.
7+
By contrast, 6 is _not_ a prime number as it not only divisible by 1 and itself, but also by 2 and 3.
8+
9+
To use the Sieve of Eratosthenes, first, write out all the numbers from 2 up to and including your given number.
10+
Then, follow these steps:
11+
12+
1. Find the next unmarked number (skipping over marked numbers).
13+
This is a prime number.
14+
2. Mark all the multiples of that prime number as **not** prime.
15+
16+
Repeat the steps until you've gone through every number.
17+
At the end, all the unmarked numbers are prime.
18+
19+
~~~~exercism/note
20+
The Sieve of Eratosthenes marks off multiples of each prime using addition (repeatedly adding the prime) or multiplication (directly computing its multiples), rather than checking each number for divisibility.
21+
22+
The tests don't check that you've implemented the algorithm, only that you've come up with the correct primes.
23+
~~~~
24+
25+
## Example
26+
27+
Let's say you're finding the primes less than or equal to 10.
28+
29+
- Write out 2, 3, 4, 5, 6, 7, 8, 9, 10, leaving them all unmarked.
30+
31+
```text
32+
2 3 4 5 6 7 8 9 10
33+
```
34+
35+
- 2 is unmarked and is therefore a prime.
36+
Mark 4, 6, 8 and 10 as "not prime".
37+
38+
```text
39+
2 3 [4] 5 [6] 7 [8] 9 [10]
40+
41+
```
42+
43+
- 3 is unmarked and is therefore a prime.
44+
Mark 6 and 9 as not prime _(marking 6 is optional - as it's already been marked)_.
45+
46+
```text
47+
2 3 [4] 5 [6] 7 [8] [9] [10]
48+
49+
```
50+
51+
- 4 is marked as "not prime", so we skip over it.
52+
53+
```text
54+
2 3 [4] 5 [6] 7 [8] [9] [10]
55+
56+
```
57+
58+
- 5 is unmarked and is therefore a prime.
59+
Mark 10 as not prime _(optional - as it's already been marked)_.
60+
61+
```text
62+
2 3 [4] 5 [6] 7 [8] [9] [10]
63+
64+
```
65+
66+
- 6 is marked as "not prime", so we skip over it.
67+
68+
```text
69+
2 3 [4] 5 [6] 7 [8] [9] [10]
70+
71+
```
72+
73+
- 7 is unmarked and is therefore a prime.
74+
75+
```text
76+
2 3 [4] 5 [6] 7 [8] [9] [10]
77+
78+
```
79+
80+
- 8 is marked as "not prime", so we skip over it.
81+
82+
```text
83+
2 3 [4] 5 [6] 7 [8] [9] [10]
84+
85+
```
86+
87+
- 9 is marked as "not prime", so we skip over it.
88+
89+
```text
90+
2 3 [4] 5 [6] 7 [8] [9] [10]
91+
92+
```
93+
94+
- 10 is marked as "not prime", so we stop as there are no more numbers to check.
95+
96+
```text
97+
2 3 [4] 5 [6] 7 [8] [9] [10]
98+
99+
```
100+
101+
You've examined all the numbers and found that 2, 3, 5, and 7 are still unmarked, meaning they're the primes less than or equal to 10.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Introduction
2+
3+
You bought a big box of random computer parts at a garage sale.
4+
You've started putting the parts together to build custom computers.
5+
6+
You want to test the performance of different combinations of parts, and decide to create your own benchmarking program to see how your computers compare.
7+
You choose the famous "Sieve of Eratosthenes" algorithm, an ancient algorithm, but one that should push your computers to the limits.
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+
"Sieve.pas"
8+
],
9+
"test": [
10+
"TestCases.pas"
11+
],
12+
"example": [
13+
".meta/example.pas"
14+
]
15+
},
16+
"blurb": "Use the Sieve of Eratosthenes to find all the primes from 2 up to a given number.",
17+
"source": "Sieve of Eratosthenes at Wikipedia",
18+
"source_url": "https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes"
19+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
unit Sieve;
2+
3+
{$mode ObjFPC}{$H+}
4+
5+
interface
6+
7+
type
8+
TIntArray = Array Of Integer;
9+
TBoolArray = Array Of Boolean;
10+
11+
function primes(
12+
const limit : Integer
13+
) : TIntArray;
14+
15+
implementation
16+
17+
uses SysUtils;
18+
19+
function primes(
20+
const limit : Integer
21+
) : TIntArray;
22+
var
23+
table : TBoolArray = ();
24+
p : Integer;
25+
n : Integer;
26+
begin
27+
SetLength(table, limit + 1);
28+
for n := Low(table) to High(table) do
29+
table[n] := true;
30+
31+
result := [];
32+
for p := 2 to limit do
33+
if table[p] then
34+
begin
35+
insert(p, result, Length(result));
36+
37+
n := p * p;
38+
while n <= limit do
39+
begin
40+
table[n] := false;
41+
n := n + p;
42+
end;
43+
end;
44+
end;
45+
46+
end.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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+
[88529125-c4ce-43cc-bb36-1eb4ddd7b44f]
13+
description = "no primes under two"
14+
15+
[4afe9474-c705-4477-9923-840e1024cc2b]
16+
description = "find first prime"
17+
18+
[974945d8-8cd9-4f00-9463-7d813c7f17b7]
19+
description = "find primes up to 10"
20+
21+
[2e2417b7-3f3a-452a-8594-b9af08af6d82]
22+
description = "limit is prime"
23+
24+
[92102a05-4c7c-47de-9ed0-b7d5fcd00f21]
25+
description = "find primes up to 1000"

exercises/practice/sieve/Makefile

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)"

exercises/practice/sieve/Sieve.pas

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
unit Sieve;
2+
3+
{$mode ObjFPC}{$H+}
4+
5+
interface
6+
7+
type
8+
TIntArray = Array Of Integer;
9+
10+
function primes(
11+
const limit : Integer
12+
) : TIntArray;
13+
14+
implementation
15+
16+
uses SysUtils;
17+
18+
function primes(
19+
const limit : Integer
20+
) : TIntArray;
21+
begin
22+
23+
raise ENotImplemented.Create('Please implement your solution.'); result := [limit];
24+
25+
end;
26+
27+
end.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
unit TestCases;
2+
3+
{$mode ObjFPC}{$H+}
4+
5+
interface
6+
7+
uses Classes, SysUtils, FPCUnit, TestRegistry, FPCUnitTestUtils;
8+
9+
type
10+
SieveTest = class(TTestCase)
11+
published
12+
procedure no_primes_under_two;
13+
procedure find_first_prime;
14+
procedure find_primes_up_to_10;
15+
procedure limit_is_prime;
16+
procedure find_primes_up_to_1000;
17+
end;
18+
19+
implementation
20+
21+
uses Sieve;
22+
23+
// 88529125-c4ce-43cc-bb36-1eb4ddd7b44f
24+
procedure SieveTest.no_primes_under_two;
25+
var
26+
expect : TIntArray;
27+
actual : TIntArray;
28+
begin
29+
expect := [];
30+
actual := Sieve.primes(1);
31+
TapAssertTrue(Self, 'no primes under two', expect, actual);
32+
end;
33+
34+
// 4afe9474-c705-4477-9923-840e1024cc2b
35+
procedure SieveTest.find_first_prime;
36+
var
37+
expect : TIntArray;
38+
actual : TIntArray;
39+
begin
40+
expect := [2];
41+
actual := Sieve.primes(2);
42+
TapAssertTrue(Self, 'find first prime', expect, actual);
43+
end;
44+
45+
// 974945d8-8cd9-4f00-9463-7d813c7f17b7
46+
procedure SieveTest.find_primes_up_to_10;
47+
var
48+
expect : TIntArray;
49+
actual : TIntArray;
50+
begin
51+
expect := [2, 3, 5, 7];
52+
actual := Sieve.primes(10);
53+
TapAssertTrue(Self, 'find primes up to 10', expect, actual);
54+
end;
55+
56+
// 2e2417b7-3f3a-452a-8594-b9af08af6d82
57+
procedure SieveTest.limit_is_prime;
58+
var
59+
expect : TIntArray;
60+
actual : TIntArray;
61+
begin
62+
expect := [2, 3, 5, 7, 11, 13];
63+
actual := Sieve.primes(13);
64+
TapAssertTrue(Self, 'limit is prime', expect, actual);
65+
end;
66+
67+
// 92102a05-4c7c-47de-9ed0-b7d5fcd00f21
68+
procedure SieveTest.find_primes_up_to_1000;
69+
var
70+
expect : TIntArray;
71+
actual : TIntArray;
72+
begin
73+
expect := [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];
74+
actual := Sieve.primes(1000);
75+
TapAssertTrue(Self, 'find primes up to 1000', expect, actual);
76+
end;
77+
78+
initialization
79+
RegisterTest(SieveTest);
80+
81+
end.

0 commit comments

Comments
 (0)