app "prime" packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.7.1/Icc3xJoIixF3hCcfXrDwLCu4wQHtNdPyoJkEbkgIElA.tar.br" } imports [pf.Stdout, pf.Task] provides [main] to pf main : Task.Task {} I32 main = numStrings = List.range { start: At 0u64, end: At 1_000_000u64 } |> List.map \e -> isPrimePre e |> List.walk [] primeWalk |> List.map Num.toStr |> Str.joinWith "\n" Stdout.line "$(numStrings)" PrimeResult : [No U64, Yes U64, Maybe U64] primeWalk : List U64, PrimeResult -> List U64 primeWalk = \l, n -> when n is Yes n2 -> List.append l n2 Maybe n2 -> if isPrimePost l n2 then List.append l n2 else l No _ -> l isPrimePre : U64 -> PrimeResult isPrimePre = \n -> if n < 2 then No n else if n < 4 then Yes n else if (firstPrimes |> List.any \p -> n > p && n % p == 0) then No n else Maybe n isPrimePost : List U64, U64 -> Bool isPrimePost = \l, n -> nFloat = Num.toF64 n valLimit = Num.ceiling (Num.sqrt nFloat) # approximate the number of primes < sqrt(n) to limit the range we have to check with a 25% error tolerance valLimitF = Num.toF64 valLimit limit = Num.ceiling (valLimitF * 1.25 / (Num.log valLimitF)) l |> List.sublist { start: 0, len: limit } |> List.dropIf \p -> p > valLimit |> List.any \p -> n % p == 0 |> Bool.not firstPrimes = [2, 3, 5, 7, 9, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 51, 67, 71, 73, 79, 83, 89, 97]