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 )