summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sieve.kpl78
1 files changed, 78 insertions, 0 deletions
diff --git a/sieve.kpl b/sieve.kpl
new file mode 100644
index 0000000..e3b89a5
--- /dev/null
+++ b/sieve.kpl
@@ -0,0 +1,78 @@
+
+// Asynchronous and Synchronous Sieve of Eratosthenes
+
+sieve_init : ([I64.n]
+ ? n > 1 {
+ `value +(n; 1) `array ([index] ? index > 1 { `true } { `false })
+ } {
+ `error "Sieve argument must be a value greater then 1"
+ }
+)
+
+sieve_get_primes : ([%ref Array[Bool].table]
+ ([result; value; index]
+ ? value { result `push index }
+ result
+ ) `reduce (Array[I64] $ (); table)
+)
+
+`export sieve_process : ([I64.n]
+ table : %shared sieve_init `sync n
+ find : ([prime; n]
+ sub_tasks : Array[`async_type find] $ ()
+ not_prime : Array[I64] $ ()
+ @ +(1; prime) .. n {[check]
+ ? check % prime {
+ ? ^ table {[t] t `get check } { sub_tasks `push find `aysnc (check; n) }
+ } {
+ not_prime `push check
+ }
+ }
+ ^ table {[t] @ not_prime {[value] t `set (value; `false) } }
+ `await sub_tasks
+ )
+ find `sync (2; n)
+ `value ^ table {[t] sieve_get_primes `sync t }
+)
+
+`export sieve_native : ([I64.n]
+ table : sieve_init `sync n
+ prime : 2
+ @ prime < n {
+ @ ! table `get prime { prime +: 1 }
+ multiplier : 2
+ @ {
+ result : prime * multiplier
+ multiplier +: 1
+ ? result > n { `break }
+ table `set (result; `false)
+ }
+ prime +: 1
+ }
+ `value sieve_get_primes `sync table
+)
+
+`is_main ([]
+ `use "sys" [args]
+ ? 4 != `length args {
+ `return `error String $ (
+ "#BOLD#RED#Got: %#\n" `format " " `join args
+ "#BOLD#WHITE#Usage: % % <-sync|-async> <n>#\n" `format (args `get 0; args `get 1)
+ )
+ }
+ n : I64 $ args `get -1
+ primes : # args `get -2 {
+ "-sync" {
+ `log "#BOLD#CYAN#CALLING SYNC#\n"
+ sieve_native `sync n
+ }
+ "-async" {
+ `log "#BOLD#CYAN#CALLING ASYNC#\n"
+ sieve_process `sync n
+ }
+ { `return `error "#BOLD#RED#First argument must be -sync or -async#\n" }
+ }
+ `log primes
+ `log "#BOLD#GREEN#COMPLETE#\n"
+ `value
+)