How to resolve the algorithm Emirp primes step by step in the Haskell programming language
How to resolve the algorithm Emirp primes step by step in the Haskell programming language
Table of Contents
Problem Statement
An emirp (prime spelled backwards) are primes that when reversed (in their decimal representation) are a different prime. (This rules out palindromic primes.)
In each list, the numbers should be in order. Invoke the (same) program once per task requirement, this will show what limit is used as the upper bound for calculating surplus (regular) primes. The specific method of how to determine if a range or if specific values are to be shown will be left to the programmer.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Emirp primes step by step in the Haskell programming language
The code you provided implements the computation of emirp numbers in Haskell.
An emirp number is a prime number that becomes a different prime number when its digits are reversed. For example, 17 is an emirp number because its reverse, 71, is also a prime number.
The code starts by defining a function called startDigOK
that checks if the first digit of a number is 1, 3, 7, or 9. This is an optimization because emirp numbers must have an odd number of digits and the first digit must be one of these four digits.
The next function, filtPrimes
, generates an infinite list of primes that have an acceptable first digit. This is done by filtering the list of all primes (primes
) using the startDigOK
function.
The function nDigsFPr
takes a number n
and returns a finite list of primes that have an acceptable first digit and are n
digits in length. This is done by taking the first n
primes from the list of filtered primes (filtPrimes
).
The function nDigsFPrHS
takes a number n
and returns a hash set of the primes that have an acceptable first digit and are n
digits in length. This is done by converting the list of primes returned by nDigsFPr
to a hash set using the fromList
function from the Data.HashSet
module.
The function fPrByDigs
generates an infinite list of hash sets, where each hash set contains primes of a specific number of digits. The first hash set contains the 1-digit primes, the second hash set contains the 2-digit primes, and so on.
The function isEmirp
takes a number n
and checks if it is an emirp number. This is done by first checking if the number has an acceptable first digit using the startDigOK
function. If the number does not have an acceptable first digit, then it cannot be an emirp number. If the number does have an acceptable first digit, then the function reverses the number and checks if the reversed number is a prime number that is different from the original number. If the reversed number is a prime number and is different from the original number, then the number is an emirp number.
The code then defines a list of emirp numbers by filtering the list of primes (primes
) using the isEmirp
function.
The function emirpSlice
takes two numbers, from
and to
, and returns a list of emirp numbers that are between from
and to
. This is done by taking the slice of the list of emirp numbers (emirps
) that starts at index from
and ends at index to
.
The function emirpValues
takes two numbers, lo
and hi
, and returns a list of emirp numbers that are between lo
and hi
. This is done by dropping the emirp numbers that are less than lo
from the list of emirp numbers (emirps
) and then taking the emirp numbers that are less than or equal to hi
.
The main function takes two command-line arguments, lo
and hi
, and computes the list of emirp numbers that are between lo
and hi
. The main function then prints the list of emirp numbers to the standard output.
Source code in the haskell programming language
#!/usr/bin/env runghc
import Data.HashSet (HashSet, fromList, member)
import Data.List
import Data.Numbers.Primes
import System.Environment
import System.Exit
import System.IO
-- optimization mentioned on the talk page
startDigOK :: Integer -> Bool
startDigOK n = head (show n) `elem` "1379"
-- infinite list of primes that have an acceptable first digit
filtPrimes :: [Integer]
filtPrimes = filter startDigOK primes
-- finite list of primes that have an acceptable first digit and
-- are the specified number of digits in length
nDigsFPr :: Integer -> [Integer]
nDigsFPr n =
takeWhile (< hi) $ dropWhile (< lo) filtPrimes
where lo = 10 ^ (n - 1)
hi = 10 ^ n
-- hash set of the filtered primes of the specified number of digits
nDigsFPrHS :: Integer -> HashSet Integer
nDigsFPrHS n = fromList $ nDigsFPr n
-- infinite list of hash sets, where each hash set contains primes of
-- a specific number of digits, i. e. index 2 contains 2 digit primes,
-- index 3 contains 3 digit primes, etc.
-- Don't access index 0, because it will return an error
fPrByDigs :: [HashSet Integer]
fPrByDigs = map nDigsFPrHS [0 ..]
isEmirp :: Integer -> Bool
isEmirp n =
let revStr = reverse $ show n
reversed = read revStr
hs = fPrByDigs !! length revStr
in (startDigOK n) && (reversed /= n) && (reversed `member` hs)
emirps :: [Integer]
emirps = filter isEmirp primes
emirpSlice :: Integer -> Integer -> [Integer]
emirpSlice from to =
genericTake numToTake $ genericDrop numToDrop emirps
where
numToDrop = from - 1
numToTake = 1 + to - from
emirpValues :: Integer -> Integer -> [Integer]
emirpValues lo hi =
dropWhile (< lo) $ takeWhile (<= hi) emirps
usage = do
name <- getProgName
putStrLn $ "usage: " ++ name ++ " lo hi [slice | values]"
exitFailure
main = do
hSetBuffering stdout NoBuffering
args <- getArgs
fixedArgs <- case length args of
1 -> return $ args ++ args ++ ["slice"]
2 -> return $ args ++ ["slice"]
3 -> return args
_ -> usage
let lo = read $ fixedArgs !! 0
hi = read $ fixedArgs !! 1
case fixedArgs !! 2 of
"slice" -> print $ emirpSlice lo hi
"values" -> print $ emirpValues lo hi
_ -> usage
λ> let emirp p = let q=(read.reverse.show) p in q /= p && noDivsBy primesW q
λ> take 20 . filter emirp $ primesW
[13,17,31,37,71,73,79,97,107,113,149,157,167,179,199,311,337,347,359,389]
λ> filter emirp . takeWhile (< 8000) . dropWhile (< 7700) $ primesW
[7717,7757,7817,7841,7867,7879,7901,7927,7949,7951,7963] -- 0.02 secs
λ> (!! (10000-1)) . filter emirp $ primesW
948349 -- 0.69 secs
You may also check:How to resolve the algorithm Inheritance/Multiple step by step in the DWScript programming language
You may also check:How to resolve the algorithm HTTP step by step in the Sidef programming language
You may also check:How to resolve the algorithm Menu step by step in the Pascal programming language
You may also check:How to resolve the algorithm Find the last Sunday of each month step by step in the Elixir programming language
You may also check:How to resolve the algorithm Quine step by step in the F# programming language