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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| -- creation de la liste des diviseurs possibles
lst_nb :: Int -> [Int]
lst_nb n = let x = div n 2 in [1..x]
-- Teste si y est un diviseur de x
is_diviseur :: Int -> Int -> Bool
is_diviseur x y = 0 == mod x y
-- retourne la somme des diviseurs d'un nombre
somme_div :: Int -> Int
-- somme_div x = foldl (+) 0 (filter (is_diviseur x) (lst_nb x))
somme_div x = div (sum $ divisors x False) 2
-- teste la "perfection" d'un nombre
is_perfect :: Int -> Bool
is_perfect x = x == somme_div x
-- liste des nombres parfaits
list_perfect :: Int -> [Int]
list_perfect y = filter (is_perfect) [1..y]
-- Integral square root of an Integral
-- long division method
isqrtLD :: Integral i => i -> i
isqrtLD n =
let lDiv n b
| n<0 = b - 1
| otherwise =
let n' = n - b
b' = b + 1
n'' = n' - b'
in lDiv n'' b'
in lDiv n 0
-- list of prime numbers
primes :: [Int]
primes = sieve (2:[3,5..])
where
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]
-- prime factors of an integer
-- e.g. 1,008 -> [2,2,2,2,3,3,7]
primeFactors :: Int -> [Int]
primeFactors nb =
factors primes nb
where
sqr = isqrtLD nb
factors qs@(p:ps) n
| p > sqr = if n == 1 then [] else [n]
| m == 0 = p : factors qs d
| otherwise = factors ps n
where (d,m) = n `divMod` p
-- take nb and gets a list of its factors listed in successive powers
-- e.g. 504
-- primeFactors -> [2, 2, 2, 3, 3, 7]
-- group -> [[2, 2, 2], [3, 3], [7]]
-- result -> [[1,2,4,8],[1,3,9],[1,7]]
powersOfPrimeFactors :: Int -> [[Int]]
powersOfPrimeFactors nb =
let pfct = group $ primeFactors nb
mapAcc accSameFactor =
snd $ mapAccumL (\acc x-> let m = acc*x in (m, m)) 1 accSameFactor
in map (1:) $ map mapAcc pfct
-- gives the list of divisors (unsorted or sorted depending on bool) of
-- an integer
-- e.g. 496 False -> [1,31,2,62,4,124,8,248,16,496]
-- 8128 True -> [1,2,4,8,16,32,64,127,254,508,1016,2032,4064,8128]
divisors :: Int -> Bool -> [Int]
divisors n bSort =
let p = powersOfPrimeFactors n
multList fct1 fct2 = -- fct1 >>= \x -> map (x*) fct2
do
x <- fct1
y <- fct2
return (x*y)
r = foldl multList [1] p
in if bSort then (sort r) else r |
Partager