-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathP39.hs
More file actions
43 lines (39 loc) · 1.37 KB
/
P39.hs
File metadata and controls
43 lines (39 loc) · 1.37 KB
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
module Arithmetic.P39 where
import qualified Data.Array as A
import qualified Data.Array.Unboxed as AU
{-
Problem 39: (*) A list of prime numbers in a given range.
Given a range of integers by its lower and upper limit,
construct a list of all prime numbers in that range.
ANSWER:
Code copied from https://wiki.haskell.org/Prime_numbers,
explanation my own.
-}
primesR :: Int -> Int -> [Int]
primesR a b = if a < 3 then 2 : xs else xs
where
xs = [i | i <- [o, o + 2 .. b], arr A.! i]
-- First odd in the segment.
o = max (a + fromEnum (even a)) 3
r = floor . sqrt $ (fromIntegral b :: Float) + 1
arr =
-- Create a boolean array indexed from o to b;
-- the indices produced by the association list
-- are set to false.
AU.accumArray
(\_ _ -> False) -- accumulating fn
-- Default value, used when the index
-- is not present in the association list.
True
(o, b) -- bounds of the array
[ (i, ()) -- association list
| p <- [3, 5 .. r],
-- Flip every multiple of an odd to False.
let q = p * p
s = 2 * p
-- Difference between divMod and quotRem.
-- https://stackoverflow.com/a/339823/839733
(n, x) = quotRem (o - q) s
q2 = if o <= q then q else q + (n + signum x) * s,
i <- [q2, q2 + s .. b]
]