How to resolve the algorithm Chowla numbers step by step in the Haskell programming language

Published on 7 June 2024 03:52 AM

How to resolve the algorithm Chowla numbers step by step in the Haskell programming language

Table of Contents

Problem Statement

Chowla numbers are also known as:

The chowla number of   n   is   (as defined by Chowla's function):

The sequence is named after   Sarvadaman D. S. Chowla,   (22 October 1907 ──► 10 December 1995), a London born Indian American mathematician specializing in number theory.

German mathematician Carl Friedrich Gauss (1777─1855) said:

Chowla numbers can also be expressed as:

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Chowla numbers step by step in the Haskell programming language

The Haskell code you provided implements the computation of the Chowla function for a range of numbers, up to 35 million.

The chowla function takes a positive integer n as input and returns the value of the Chowla function for that number. The Chowla function is defined as follows:

chowla(n) = n - product(sumFactor(p^e) for (p, e) in factorisation(n))

where factorisation(n) is the prime factorisation of n, sumFactor(p^e) is the sum of p^k for k in [1, e], and product is the product of the values obtained by applying sumFactor to each prime factor of n.

The chowlas function takes a list of positive integers as input and returns a list of tuples, where each tuple consists of a number and the value of the Chowla function for that number. The chowlas function uses parallel processing to compute the Chowla function for each number in the input list.

The chowlaPrimes function takes a list of tuples, where each tuple consists of a number and the value of the Chowla function for that number, and a range of numbers as input. The chowlaPrimes function returns the number of primes in the given range that have a Chowla function value that is equal to the second element of the given tuple.

The chowlaPerfects function takes a list of tuples, where each tuple consists of a number and the value of the Chowla function for that number, as input. The chowlaPerfects function returns a list of the numbers in the input list that are perfect numbers. A perfect number is a number that is equal to the sum of its proper divisors.

The commas function takes a positive integer as input and returns a string representation of that number with commas separating the thousands, millions, etc.

The main function is the entry point of the program. The main function first sets the number of threads to use to the number of cores available on the computer. Then, the main function computes the Chowla function for the first 37 numbers, the number of primes in several ranges of numbers that have a Chowla function value that is equal to the Chowla function value of the perfect number closest to the upper bound of the range, and the list of perfect numbers less than 35 million. Finally, the main function prints the results to the console.

Source code in the haskell programming language

import Control.Concurrent       (setNumCapabilities)
import Control.Monad.Par        (runPar, get, spawnP)
import Control.Monad            (join, (>=>))
import Data.List.Split          (chunksOf)
import Data.List                (intercalate, mapAccumL, genericTake, genericDrop)
import Data.Bifunctor           (bimap)
import GHC.Conc                 (getNumProcessors)
import Math.NumberTheory.Primes (factorise, unPrime)
import Text.Printf              (printf)

chowla :: Word -> Word
chowla 1 = 0
chowla n = f n
  where
    f = (-) =<< pred . product . fmap sumFactor . factorise
    sumFactor (n, e) = foldr (\p s -> s + unPrime n^p) 1 [1..e]

chowlas :: [Word] -> [(Word, Word)]
chowlas [] = []
chowlas xs = runPar $ join <$>
  (mapM (spawnP . fmap ((,) <*> chowla)) >=> mapM get) (chunksOf (10^6) xs)

chowlaPrimes :: [(Word, Word)] -> (Word, Word) -> (Word, Word)
chowlaPrimes chowlas range = (count chowlas, snd range)
  where
    isPrime (1, n) = False
    isPrime (_, n) = n == 0
    count = fromIntegral . length . filter isPrime . between range
    between (min, max) = genericTake (max - pred min) . genericDrop (pred min)

chowlaPerfects :: [(Word, Word)] -> [Word]
chowlaPerfects = fmap fst . filter isPerfect
  where 
    isPerfect (1, _) = False
    isPerfect (n, c) = c == pred n

commas :: (Show a, Integral a) => a -> String
commas = reverse . intercalate "," . chunksOf 3 . reverse . show

main :: IO ()
main = do
  cores <- getNumProcessors
  setNumCapabilities cores
  printf "Using %d cores\n" cores

  mapM_ (uncurry (printf "chowla(%2d) = %d\n")) $ take 37 allChowlas
  mapM_ (uncurry (printf "There are %8s primes < %10s\n"))
    (chowlaP
       [ (1, 10^2)
       , (succ $ 10^2, 10^3)
       , (succ $ 10^3, 10^4)
       , (succ $ 10^4, 10^5)
       , (succ $ 10^5, 10^6)
       , (succ $ 10^6, 10^7) ])

  mapM_ (printf "%10s is a perfect number.\n" . commas) perfects
  printf "There are %2d perfect numbers < 35,000,000\n" $ length perfects
  where
    chowlaP = fmap (bimap commas commas) . snd
      . mapAccumL (\total (count, max) -> (total + count, (total + count, max))) 0
      . fmap (chowlaPrimes $ take (10^7) allChowlas)
    perfects = chowlaPerfects allChowlas
    allChowlas = chowlas [1..35*10^6]


  

You may also check:How to resolve the algorithm List comprehensions step by step in the D programming language
You may also check:How to resolve the algorithm EKG sequence convergence step by step in the Java programming language
You may also check:How to resolve the algorithm Terminal control/Display an extended character step by step in the COBOL programming language
You may also check:How to resolve the algorithm Juggler sequence step by step in the Ada programming language
You may also check:How to resolve the algorithm Longest common substring step by step in the Common Lisp programming language