From 59af703f7730a81671042f2733259b469c38cb15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Sun, 19 Jan 2025 22:23:48 -0800 Subject: [PATCH] Add `sieve` (#144) --- config.json | 8 ++++ .../practice/sieve/.docs/instructions.md | 42 +++++++++++++++++ .../practice/sieve/.docs/introduction.md | 7 +++ exercises/practice/sieve/.meta/config.json | 19 ++++++++ .../practice/sieve/.meta/src/example.art | 23 +++++++++ exercises/practice/sieve/.meta/tests.toml | 25 ++++++++++ exercises/practice/sieve/src/sieve.art | 3 ++ exercises/practice/sieve/tester.art | 3 ++ exercises/practice/sieve/tests/test-sieve.art | 47 +++++++++++++++++++ 9 files changed, 177 insertions(+) create mode 100644 exercises/practice/sieve/.docs/instructions.md create mode 100644 exercises/practice/sieve/.docs/introduction.md create mode 100644 exercises/practice/sieve/.meta/config.json create mode 100644 exercises/practice/sieve/.meta/src/example.art create mode 100644 exercises/practice/sieve/.meta/tests.toml create mode 100644 exercises/practice/sieve/src/sieve.art create mode 100644 exercises/practice/sieve/tester.art create mode 100644 exercises/practice/sieve/tests/test-sieve.art diff --git a/config.json b/config.json index dda2763..6e04be7 100644 --- a/config.json +++ b/config.json @@ -381,6 +381,14 @@ "prerequisites": [], "difficulty": 3 }, + { + "slug": "sieve", + "name": "Sieve", + "uuid": "dcb4854d-0ec9-48a9-82ec-3e60f9f0433e", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "space-age", "name": "Space Age", diff --git a/exercises/practice/sieve/.docs/instructions.md b/exercises/practice/sieve/.docs/instructions.md new file mode 100644 index 0000000..085c0a5 --- /dev/null +++ b/exercises/practice/sieve/.docs/instructions.md @@ -0,0 +1,42 @@ +# Instructions + +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. + +A prime number is a number larger than 1 that is only divisible by 1 and itself. +For example, 2, 3, 5, 7, 11, and 13 are prime numbers. +By contrast, 6 is _not_ a prime number as it not only divisible by 1 and itself, but also by 2 and 3. + +To use the Sieve of Eratosthenes, you first create a list of all the numbers between 2 and your given number. +Then you repeat the following steps: + +1. Find the next unmarked number in your list (skipping over marked numbers). + This is a prime number. +2. Mark all the multiples of that prime number as **not** prime. + +You keep repeating these steps until you've gone through every number in your list. +At the end, all the unmarked numbers are prime. + +~~~~exercism/note +The tests don't check that you've implemented the algorithm, only that you've come up with the correct list of primes. +To check you are implementing the Sieve correctly, a good first test is to check that you do not use division or remainder operations. +~~~~ + +## Example + +Let's say you're finding the primes less than or equal to 10. + +- List out 2, 3, 4, 5, 6, 7, 8, 9, 10, leaving them all unmarked. +- 2 is unmarked and is therefore a prime. + Mark 4, 6, 8 and 10 as "not prime". +- 3 is unmarked and is therefore a prime. + Mark 6 and 9 as not prime _(marking 6 is optional - as it's already been marked)_. +- 4 is marked as "not prime", so we skip over it. +- 5 is unmarked and is therefore a prime. + Mark 10 as not prime _(optional - as it's already been marked)_. +- 6 is marked as "not prime", so we skip over it. +- 7 is unmarked and is therefore a prime. +- 8 is marked as "not prime", so we skip over it. +- 9 is marked as "not prime", so we skip over it. +- 10 is marked as "not prime", so we stop as there are no more numbers to check. + +You've examined all numbers and found 2, 3, 5, and 7 are still unmarked, which means they're the primes less than or equal to 10. diff --git a/exercises/practice/sieve/.docs/introduction.md b/exercises/practice/sieve/.docs/introduction.md new file mode 100644 index 0000000..f6c1cf7 --- /dev/null +++ b/exercises/practice/sieve/.docs/introduction.md @@ -0,0 +1,7 @@ +# Introduction + +You bought a big box of random computer parts at a garage sale. +You've started putting the parts together to build custom computers. + +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. +You choose the famous "Sieve of Eratosthenes" algorithm, an ancient algorithm, but one that should push your computers to the limits. diff --git a/exercises/practice/sieve/.meta/config.json b/exercises/practice/sieve/.meta/config.json new file mode 100644 index 0000000..cc83356 --- /dev/null +++ b/exercises/practice/sieve/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "src/sieve.art" + ], + "test": [ + "tests/test-sieve.art" + ], + "example": [ + ".meta/src/example.art" + ] + }, + "blurb": "Use the Sieve of Eratosthenes to find all the primes from 2 up to a given number.", + "source": "Sieve of Eratosthenes at Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes" +} diff --git a/exercises/practice/sieve/.meta/src/example.art b/exercises/practice/sieve/.meta/src/example.art new file mode 100644 index 0000000..ec0c70f --- /dev/null +++ b/exercises/practice/sieve/.meta/src/example.art @@ -0,0 +1,23 @@ +primes: function [limit][ + if limit < 2 -> return [] + isPrime: array.of: inc limit true + isPrime\0: false + isPrime\1: false + + loop 2..limit 'num [ + if isPrime\[num] [ + multiple: num * num + while [multiple =< limit] [ + isPrime\[multiple]: false + 'multiple + num + ] + ] + ] + + results: [] + loop 2..limit 'num [ + if isPrime\[num] -> 'results ++ num + ] + + results +] diff --git a/exercises/practice/sieve/.meta/tests.toml b/exercises/practice/sieve/.meta/tests.toml new file mode 100644 index 0000000..fec5e1a --- /dev/null +++ b/exercises/practice/sieve/.meta/tests.toml @@ -0,0 +1,25 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[88529125-c4ce-43cc-bb36-1eb4ddd7b44f] +description = "no primes under two" + +[4afe9474-c705-4477-9923-840e1024cc2b] +description = "find first prime" + +[974945d8-8cd9-4f00-9463-7d813c7f17b7] +description = "find primes up to 10" + +[2e2417b7-3f3a-452a-8594-b9af08af6d82] +description = "limit is prime" + +[92102a05-4c7c-47de-9ed0-b7d5fcd00f21] +description = "find primes up to 1000" diff --git a/exercises/practice/sieve/src/sieve.art b/exercises/practice/sieve/src/sieve.art new file mode 100644 index 0000000..e397f44 --- /dev/null +++ b/exercises/practice/sieve/src/sieve.art @@ -0,0 +1,3 @@ +primes: function [limit][ + panic "Please implement the primes function" +] diff --git a/exercises/practice/sieve/tester.art b/exercises/practice/sieve/tester.art new file mode 100644 index 0000000..80f4a8f --- /dev/null +++ b/exercises/practice/sieve/tester.art @@ -0,0 +1,3 @@ +import {unitt}! + +runTests.failFast findTests "tests" diff --git a/exercises/practice/sieve/tests/test-sieve.art b/exercises/practice/sieve/tests/test-sieve.art new file mode 100644 index 0000000..8396199 --- /dev/null +++ b/exercises/practice/sieve/tests/test-sieve.art @@ -0,0 +1,47 @@ +import {unitt}! +import {src/sieve}! + +suite "Sieve" [ + test "no primes under two" [ + results: primes 1 + expected: [] + assert -> expected = results + ] + + test.skip "find first prime" [ + results: primes 2 + expected: [2] + assert -> expected = results + ] + + test.skip "find primes up to 10" [ + results: primes 10 + expected: [2 3 5 7] + assert -> expected = results + ] + + test.skip "limit is prime" [ + results: primes 13 + expected: [2 3 5 7 11 13] + assert -> expected = results + ] + + test.skip "find primes up to 1000" [ + results: primes 1000 + expected: [ + 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 + ] + assert -> expected = results + ] +]