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]