Skip to content

Commit

Permalink
lpils notes
Browse files Browse the repository at this point in the history
  • Loading branch information
bcpeinhardt authored and lpil committed Feb 15, 2024
1 parent 7f1a99c commit 39b9796
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 25 deletions.
53 changes: 29 additions & 24 deletions exercises/practice/sieve/.meta/example.gleam
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import gleam/list
import gleam/iterator
import gleam/bool
import gleam/set.{type Set}

pub fn primes_up_to(upper_bound: Int) -> List(Int) {
// 2 is the first prime number. Smaller input values are invalid.
Expand All @@ -10,41 +11,45 @@ pub fn primes_up_to(upper_bound: Int) -> List(Int) {
let possible_primes = list.range(from: 2, to: upper_bound)

// Run the sieve algorithm on the list of possible primes.
sieve([], [], possible_primes, upper_bound)
sieve([], set.new(), possible_primes, upper_bound)
|> list.reverse
}

fn sieve(
primes: List(Int),
composites: List(Int),
composites: Set(Int),
candidates: List(Int),
upper_bound: Int,
) -> List(Int) {
// BASE CASE: If there are no more candidates, we're done.
use <- bool.guard(when: list.is_empty(candidates), return: primes)
let assert [next, ..rest] = candidates
case candidates {
// BASE CASE: If there are no more candidates, we're done.
[] -> primes

case list.contains(composites, next) {
// If the next candidate is a multiple of one of our discovered primes, skip it
True -> sieve(primes, composites, rest, upper_bound)
[next, ..rest] -> {
case set.contains(composites, next) {
// If the next candidate is a multiple of one of our discovered primes, skip it
True -> sieve(primes, composites, rest, upper_bound)

// The next candidate is not a multiple of any of our discovered primes, so it's prime.
False -> {
// Generate a list from n^2 to the upper bound of the multiples of
// our newly discovered prime.
let multiples =
iterator.iterate(next * next, fn(state) { state + next })
|> iterator.take_while(fn(n) { n <= upper_bound })
|> iterator.to_list
// The next candidate is not a multiple of any of our discovered primes, so it's prime.
False -> {
// Generate a list from n^2 to the upper bound of the multiples of
// our newly discovered prime.
let multiples =
iterator.iterate(next * next, fn(state) { state + next })
|> iterator.take_while(fn(n) { n <= upper_bound })
|> iterator.to_list
|> set.from_list

// Add the newly discovered prime to the list of primes, and
// add the multiples of the prime to the list of composites.
sieve(
[next, ..primes],
list.append(composites, multiples),
rest,
upper_bound,
)
// Add the newly discovered prime to the list of primes, and
// add the multiples of the prime to the list of composites.
sieve(
[next, ..primes],
set.union(composites, multiples),
rest,
upper_bound,
)
}
}
}
}
}
2 changes: 1 addition & 1 deletion exercises/practice/sieve/src/sieve.gleam
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub fn primes_up_to(upper_bound upper_bound: Int) -> List(Int) {
pub fn primes_up_to(upper_bound: Int) -> List(Int) {
todo
}

0 comments on commit 39b9796

Please sign in to comment.