How to resolve the algorithm Emirp primes step by step in the Haskell programming language

Published on 7 June 2024 03:52 AM

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