How to resolve the algorithm Proper divisors step by step in the Haskell programming language

Published on 7 June 2024 03:52 AM

How to resolve the algorithm Proper divisors step by step in the Haskell programming language

Table of Contents

Problem Statement

The   proper divisors   of a positive integer N are those numbers, other than N itself, that divide N without remainder. For N > 1 they will always include 1,   but for N == 1 there are no proper divisors.

The proper divisors of     6     are   1, 2, and 3. The proper divisors of   100   are   1, 2, 4, 5, 10, 20, 25, and 50.

Show all output here.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Proper divisors step by step in the Haskell programming language

Both snippets of code are written in Haskell

First snippet:

  • The first function, divisors, takes an integral number as input and returns a list of its divisors. A divisor of a number is a number that divides evenly into the number.
  • The divisors function uses the filter function to filter out all the numbers that do not divide evenly into the input number.
  • The filter function takes a predicate as its first argument and a list as its second argument. The predicate is a function that returns a Boolean value, and the filter function returns a list of all the elements of the list that satisfy the predicate.
  • The predicate in the divisors function checks if the remainder of the division of the input number by the current number in the list is 0.
  • The input to the filter function is the range of numbers from 1 to half of the input number.

Second snippet:

  • The second snippet includes a slightly more refined version of the divisors function from the first snippet. This function, properDivisors, excludes the input number itself from the list of divisors, so it only returns the proper divisors of the number.
  • The properDivisors function uses a combination of the floor, sqrt, fromIntegral, filter, init, rem, bool, id, and tail functions to compute the proper divisors of the input number.
  • The floor function rounds a real number down to the nearest integer.
  • The sqrt function computes the square root of a number.
  • The fromIntegral function converts an integer to a real number.
  • The init function removes the last element from a list.
  • The bool function takes three arguments: a Boolean value, a value to return if the Boolean value is true, and a value to return if the Boolean value is false.
  • The id function returns its input unchanged.
  • The tail function removes the first element from a list.

Both snippets:

  • Both snippets use the mapM_ function to apply a function to each element of a list.
  • The mapM_ function takes a function and a list as its arguments. The function is applied to each element of the list, and the results are returned as a list.
  • The print function is used to print the results of the mapM_ function.

Additional notes:

  • The Integral type class is a type class that represents integral types, such as integers and floating-point numbers.
  • The Ord type class is a type class that represents ordered types, such as integers and floating-point numbers.
  • The List type class is a type class that represents lists.

Source code in the haskell programming language

import Data.Ord
import Data.List

divisors :: (Integral a) => a -> [a]
divisors n = filter ((0 ==) . (n `mod`)) [1 .. (n `div` 2)]

main :: IO ()
main = do
  putStrLn "divisors of 1 to 10:"
  mapM_ (print . divisors) [1 .. 10]
  putStrLn "a number with the most divisors within 1 to 20000 (number, count):"
  print $ maximumBy (comparing snd)
    [(n, length $ divisors n) | n <- [1 .. 20000]]


import Data.List (maximumBy)
import Data.Ord (comparing)
import Data.Bool (bool)

properDivisors
  :: Integral a
  => a -> [a]
properDivisors n =
  let root = (floor . sqrt . fromIntegral) n
      lows = filter ((0 ==) . rem n) [1 .. root]
  in init (lows ++ bool id tail (n == root * root) (reverse (quot n <$> lows)))

main :: IO ()
main = do
  putStrLn "Proper divisors of 1 to 10:"
  mapM_ (print . properDivisors) [1 .. 10]
  mapM_
    putStrLn
    [ ""
    , "A number in the range 1 to 20,000 with the most proper divisors,"
    , "as (number, count of proper divisors):"
    , ""
    ]
  print $
    maximumBy (comparing snd) $
    (,) <*> (length . properDivisors) <$> [1 .. 20000]


import Data.Numbers.Primes (primeFactors)
import Data.List (group, maximumBy, sort)
import Data.Ord (comparing)

properDivisors :: Int -> [Int]
properDivisors =
  init . sort . foldr (
    flip ((<*>) . fmap (*)) . scanl (*) 1
  ) [1] . group . primeFactors

---------------------------TEST----------------------------
main :: IO ()
main = do
  putStrLn $
    fTable "Proper divisors of [1..10]:" show show properDivisors [1 .. 10]
  mapM_
    putStrLn
    [ ""
    , "A number in the range 1 to 20,000 with the most proper divisors,"
    , "as (number, count of proper divisors):"
    , ""
    ]
  print $
    maximumBy (comparing snd) $
    (,) <*> (length . properDivisors) <$> [1 .. 20000]

--------------------------DISPLAY--------------------------
fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> String
fTable s xShow fxShow f xs =
  let rjust n c = (drop . length) <*> (replicate n c ++)
      w = maximum (length . xShow <$> xs)
  in unlines $
     s : fmap (((++) . rjust w ' ' . xShow) <*> ((" -> " ++) . fxShow . f)) xs


  

You may also check:How to resolve the algorithm Four is magic step by step in the jq programming language
You may also check:How to resolve the algorithm Permutation test step by step in the jq programming language
You may also check:How to resolve the algorithm Greatest common divisor step by step in the Haskell programming language
You may also check:How to resolve the algorithm Binary search step by step in the Lambdatalk programming language
You may also check:How to resolve the algorithm SHA-256 step by step in the Slope programming language