summaryrefslogtreecommitdiff
path: root/sieve.kpl
blob: 92fdac972ebb217fa509bd5bbbe6d40cf94b9350 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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 I64 $ index }
        result
    ) `reduce (Array[I64] $ (); table)
)

`export sieve_process : ([I64.n]
    table : %shared sieve_init `sync n
    find : ([I64.prime; I64.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
)