From be9af8833a338faad624e72dca455e5bd3cd2b19 Mon Sep 17 00:00:00 2001 From: Jeremie Gillet Date: Sat, 9 Mar 2024 13:09:05 +0900 Subject: [PATCH 1/4] Add new practice exercise `sieve` --- config.json | 16 +++++ .../practice/sieve/.docs/instructions.md | 28 ++++++++ .../practice/sieve/.docs/introduction.md | 7 ++ exercises/practice/sieve/.meta/config.json | 19 ++++++ .../sieve/.meta/src/Sieve.example.elm | 68 +++++++++++++++++++ exercises/practice/sieve/.meta/tests.toml | 25 +++++++ exercises/practice/sieve/elm.json | 29 ++++++++ exercises/practice/sieve/src/Sieve.elm | 6 ++ exercises/practice/sieve/tests/Tests.elm | 36 ++++++++++ 9 files changed, 234 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/Sieve.example.elm create mode 100644 exercises/practice/sieve/.meta/tests.toml create mode 100644 exercises/practice/sieve/elm.json create mode 100644 exercises/practice/sieve/src/Sieve.elm create mode 100644 exercises/practice/sieve/tests/Tests.elm diff --git a/config.json b/config.json index 6cf193ab..a4a73ad1 100644 --- a/config.json +++ b/config.json @@ -1217,6 +1217,22 @@ "result" ], "difficulty": 5 + }, + { + "slug": "sieve", + "name": "sieve", + "uuid": "60804d7f-8eb3-46e0-8337-45b7426456b0", + "practices": [ + "array" + ], + "prerequisites": [ + "booleans", + "maybe", + "pattern-matching", + "array", + "lists" + ], + "difficulty": 6 } ] }, diff --git a/exercises/practice/sieve/.docs/instructions.md b/exercises/practice/sieve/.docs/instructions.md new file mode 100644 index 00000000..3adf1d55 --- /dev/null +++ b/exercises/practice/sieve/.docs/instructions.md @@ -0,0 +1,28 @@ +# Instructions + +Your task is to create a program that implements the Sieve of Eratosthenes algorithm to find prime numbers. + +A prime number is a number that is only divisible by 1 and itself. +For example, 2, 3, 5, 7, 11, and 13 are prime numbers. + +The Sieve of Eratosthenes is an ancient algorithm that works by taking a list of numbers and crossing out all the numbers that aren't prime. + +A number that is **not** prime is called a "composite number". + +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. This is a prime number. +2. Mark all the multiples of that prime number as composite (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 +[Wikipedia's Sieve of Eratosthenes article][eratosthenes] has a useful graphic that explains the algorithm. + +The tests don't check that you've implemented the algorithm, only that you've come up with the correct list of primes. +A good first test is to check that you do not use division or remainder operations. + +[eratosthenes]: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes +~~~~ diff --git a/exercises/practice/sieve/.docs/introduction.md b/exercises/practice/sieve/.docs/introduction.md new file mode 100644 index 00000000..f6c1cf79 --- /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 00000000..21368f96 --- /dev/null +++ b/exercises/practice/sieve/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "jiegillet" + ], + "files": { + "solution": [ + "src/Sieve.elm" + ], + "test": [ + "tests/Tests.elm" + ], + "example": [ + ".meta/src/Sieve.example.elm" + ] + }, + "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/Sieve.example.elm b/exercises/practice/sieve/.meta/src/Sieve.example.elm new file mode 100644 index 00000000..39a6af42 --- /dev/null +++ b/exercises/practice/sieve/.meta/src/Sieve.example.elm @@ -0,0 +1,68 @@ +module Sieve exposing (primes) + +import Array exposing (Array) + + +primes : Int -> List Int +primes limit = + let + -- an array, with indices from 0 until limit, each with a Bool value representing primeness + initialSieve = + Array.initialize (limit + 1) + (\n -> + if n < 2 then + False + + else + True + ) + + initialPrime = + Just 2 + in + runSieve initialPrime initialSieve + |> Array.toIndexedList + |> List.filterMap + (\( index, isPrime ) -> + if isPrime then + Just index + + else + Nothing + ) + + +runSieve : Maybe Int -> Array Bool -> Array Bool +runSieve maybePrime sieve = + case maybePrime of + Nothing -> + sieve + + Just prime -> + let + removeMultiples : Int -> Array Bool -> Array Bool + removeMultiples multiple = + if multiple > Array.length sieve then + identity + + else + Array.set multiple False + >> removeMultiples (multiple + prime) + + sieveWithPrimeMultipleRemoved : Array Bool + sieveWithPrimeMultipleRemoved = + removeMultiples (2 * prime) sieve + + findNextPrime : Int -> Maybe Int + findNextPrime index = + case Array.get index sieveWithPrimeMultipleRemoved of + Nothing -> + Nothing + + Just True -> + Just index + + Just False -> + findNextPrime (index + 1) + in + runSieve (findNextPrime (prime + 1)) sieveWithPrimeMultipleRemoved diff --git a/exercises/practice/sieve/.meta/tests.toml b/exercises/practice/sieve/.meta/tests.toml new file mode 100644 index 00000000..fec5e1a1 --- /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/elm.json b/exercises/practice/sieve/elm.json new file mode 100644 index 00000000..22c9e137 --- /dev/null +++ b/exercises/practice/sieve/elm.json @@ -0,0 +1,29 @@ +{ + "type": "application", + "source-directories": [ + "src" + ], + "elm-version": "0.19.1", + "dependencies": { + "direct": { + "elm/core": "1.0.5", + "elm/json": "1.1.3", + "elm/parser": "1.1.0", + "elm/random": "1.0.0", + "elm/regex": "1.0.0", + "elm/time": "1.0.0" + }, + "indirect": {} + }, + "test-dependencies": { + "direct": { + "elm-explorations/test": "2.1.0", + "rtfeldman/elm-iso8601-date-strings": "1.1.4" + }, + "indirect": { + "elm/bytes": "1.0.8", + "elm/html": "1.0.0", + "elm/virtual-dom": "1.0.3" + } + } +} diff --git a/exercises/practice/sieve/src/Sieve.elm b/exercises/practice/sieve/src/Sieve.elm new file mode 100644 index 00000000..8bd231fd --- /dev/null +++ b/exercises/practice/sieve/src/Sieve.elm @@ -0,0 +1,6 @@ +module Sieve exposing (primes) + + +primes : Int -> List Int +primes limit = + Debug.todo "Please implement primes" diff --git a/exercises/practice/sieve/tests/Tests.elm b/exercises/practice/sieve/tests/Tests.elm new file mode 100644 index 00000000..3e2ee614 --- /dev/null +++ b/exercises/practice/sieve/tests/Tests.elm @@ -0,0 +1,36 @@ +module Tests exposing (tests) + +import Expect +import Sieve +import Test exposing (Test, describe, skip, test) + + +tests : Test +tests = + describe "Sieve" + [ -- skip <| + test "no primes under two" <| + \() -> + Sieve.primes 1 + |> Expect.equal [] + , skip <| + test "find first prime" <| + \() -> + Sieve.primes 2 + |> Expect.equal [ 2 ] + , skip <| + test "find primes up to 10" <| + \() -> + Sieve.primes 10 + |> Expect.equal [ 2, 3, 5, 7 ] + , skip <| + test "limit is prime" <| + \() -> + Sieve.primes 13 + |> Expect.equal [ 2, 3, 5, 7, 11, 13 ] + , skip <| + test "find primes up to 1000" <| + \() -> + Sieve.primes 1000 + |> Expect.equal [ 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 ] + ] From 77c912579c07242da4eb1c76f9effaaabe006f91 Mon Sep 17 00:00:00 2001 From: Jeremie Gillet Date: Sat, 9 Mar 2024 14:16:44 +0900 Subject: [PATCH 2/4] apply analyzer comment --- exercises/practice/sieve/.meta/src/Sieve.example.elm | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/exercises/practice/sieve/.meta/src/Sieve.example.elm b/exercises/practice/sieve/.meta/src/Sieve.example.elm index 39a6af42..e55f89fa 100644 --- a/exercises/practice/sieve/.meta/src/Sieve.example.elm +++ b/exercises/practice/sieve/.meta/src/Sieve.example.elm @@ -8,14 +8,7 @@ primes limit = let -- an array, with indices from 0 until limit, each with a Bool value representing primeness initialSieve = - Array.initialize (limit + 1) - (\n -> - if n < 2 then - False - - else - True - ) + Array.initialize (limit + 1) (\n -> n >= 2) initialPrime = Just 2 From 63ac99988988b6ef8020312884dc21ebb35ef2bc Mon Sep 17 00:00:00 2001 From: Jeremie Gillet Date: Sat, 9 Mar 2024 15:06:47 +0900 Subject: [PATCH 3/4] fix config name --- bin/generate_practice_exercise.sh | 2 +- config.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/generate_practice_exercise.sh b/bin/generate_practice_exercise.sh index 6484f056..7bad312f 100755 --- a/bin/generate_practice_exercise.sh +++ b/bin/generate_practice_exercise.sh @@ -20,7 +20,7 @@ echo "Fetching latest version of configlet..." echo "Adding instructions and configuration files..." UUID=$(bin/configlet uuid) jq --arg slug "$SLUG" --arg uuid "$UUID" \ - '.exercises.practice += [{slug: $slug, name: $slug, uuid: $uuid, practices: [], prerequisites: [], difficulty: 5}]' \ + '.exercises.practice += [{slug: $slug, name: "TODO", uuid: $uuid, practices: [], prerequisites: [], difficulty: 5}]' \ config.json > config.json.tmp mv config.json.tmp config.json diff --git a/config.json b/config.json index a4a73ad1..6c995818 100644 --- a/config.json +++ b/config.json @@ -1220,7 +1220,7 @@ }, { "slug": "sieve", - "name": "sieve", + "name": "Sieve", "uuid": "60804d7f-8eb3-46e0-8337-45b7426456b0", "practices": [ "array" From 4f234e20c2b645d7ffce22957f334145846d02a3 Mon Sep 17 00:00:00 2001 From: Jie Date: Sun, 10 Mar 2024 08:37:01 +0800 Subject: [PATCH 4/4] Update exercises/practice/sieve/.meta/src/Sieve.example.elm Co-authored-by: Cedd Burge --- exercises/practice/sieve/.meta/src/Sieve.example.elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/sieve/.meta/src/Sieve.example.elm b/exercises/practice/sieve/.meta/src/Sieve.example.elm index e55f89fa..2343cb50 100644 --- a/exercises/practice/sieve/.meta/src/Sieve.example.elm +++ b/exercises/practice/sieve/.meta/src/Sieve.example.elm @@ -33,7 +33,7 @@ runSieve maybePrime sieve = Just prime -> let - removeMultiples : Int -> Array Bool -> Array Bool + removeMultiples : Int -> (Array Bool -> Array Bool) removeMultiples multiple = if multiple > Array.length sieve then identity