41 lines
1.4 KiB
Haskell
41 lines
1.4 KiB
Haskell
import Control.Monad (guard)
|
|
import Data.List (intercalate)
|
|
import Data.List.Split (chunksOf)
|
|
import Math.NumberTheory.Primes (Prime, unPrime, nextPrime)
|
|
import Math.NumberTheory.Primes.Testing (isPrime)
|
|
import Text.Printf (printf)
|
|
|
|
data PierPointKind = First | Second
|
|
|
|
merge :: Ord a => [a] -> [a] -> [a]
|
|
merge [] b = b
|
|
merge a@(x:xs) b@(y:ys) | x < y = x : merge xs b
|
|
| otherwise = y : merge a ys
|
|
|
|
nSmooth :: Integer -> [Integer]
|
|
nSmooth p = 1 : foldr u [] factors
|
|
where
|
|
factors = takeWhile (<=p) primes
|
|
primes = map unPrime [nextPrime 1..]
|
|
u n s = r
|
|
where
|
|
r = merge s (map (n*) (1:r))
|
|
|
|
pierpoints :: PierPointKind -> [Integer]
|
|
pierpoints k = do
|
|
n <- nSmooth 3
|
|
let x = case k of First -> succ n
|
|
Second -> pred n
|
|
guard (isPrime x) >> [x]
|
|
|
|
main :: IO ()
|
|
main = do
|
|
printf "\nFirst 50 Pierpont primes of the first kind:\n"
|
|
mapM_ (\row -> mapM_ (printf "%12s" . commas) row >> printf "\n") (rows $ pierpoints First)
|
|
printf "\nFirst 50 Pierpont primes of the second kind:\n"
|
|
mapM_ (\row -> mapM_ (printf "%12s" . commas) row >> printf "\n") (rows $ pierpoints Second)
|
|
printf "\n250th Pierpont prime of the first kind: %s\n" (commas $ pierpoints First !! 249)
|
|
printf "\n250th Pierpont prime of the second kind: %s\n\n" (commas $ pierpoints Second !! 249)
|
|
where
|
|
rows = chunksOf 10 . take 50
|
|
commas = reverse . intercalate "," . chunksOf 3 . reverse . show
|