You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
1.8 KiB
Plaintext

app "prime2"
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.7.1/Icc3xJoIixF3hCcfXrDwLCu4wQHtNdPyoJkEbkgIElA.tar.br" }
imports [pf.Stdout, pf.Task, pf.Arg]
provides [main] to pf
main : Task.Task {} I32
main =
max <- Task.await parseArg
numStrings =
primesIn max
|> List.map Num.toStr
|> Str.joinWith "\n"
Stdout.line "$(numStrings)"
parseArg =
args <- Task.await (Arg.list)
arg =
args
|> List.get 1
|> Result.withDefault "50_000_000"
|> Str.toU64
when arg is
Ok a -> a |> Task.ok
Err InvalidNumStr -> crash "Passed argument is not a numberr"
primesIn : U64 -> List U64
primesIn = \n ->
numbers = List.concat [2] (List.range { start: At 3u64, end: At n, step: 2 })
primeSieve numbers n
primeSieve : List U64, U64 -> List U64
primeSieve = \l, max ->
when l is
[] -> []
[a] -> [a]
[head, ..] if (Num.powInt head 2) > max -> l
[head, .. as tail] ->
filteredList = List.dropIf tail (\e -> Num.isMultipleOf e head)
List.concat [head] (primeSieve filteredList max)
countPrimesIn : U64 -> Nat
countPrimesIn = \limit ->
List.range { start: At 2, end: At limit }
|> List.countIf \n ->
if n < 4 then
Bool.true
else if Num.isEven n then
Bool.false
else
res =
List.range { start: At 3, end: At (Num.ceiling (Num.sqrt (Num.toF64 n))), step: 2 }
|> List.any \a -> Num.isMultipleOf n a
|> Bool.not
res
expect
(
countPrimesIn 100000
|> \expected ->
dbg expected
expected
)
== (
List.len (primesIn 100000)
|> \actual ->
dbg actual
actual
)