Proper divisors: Difference between revisions

→‎{{header|Haskell}}: Added a definition of properDivisors in terms of primeFactors
(→‎{{header|Haskell}}: Added a definition of properDivisors in terms of primeFactors)
Line 2,035:
(18480,79)</pre>
 
Or, forFor a little more efficiency, filteringwe can filter only up to the root, and deriving the higher proper divisors from the lower ones, as quotients:
 
<lang haskell>import Data.List (maximumBy)
Line 2,075:
[1,3]
[1,2,5]
 
A number in the range 1 to 20,000 with the most proper divisors,
as (number, count of proper divisors):
 
(18480,79)</pre>
 
and we can also define properDivisors in terms of primeFactors:
 
<lang haskell>import Data.Numbers.Primes (primeFactors)
import Data.List (group, maximumBy, sort)
import Data.Ord (comparing)
import Control.Arrow ((&&&))
 
properDivisors :: Int -> [Int]
properDivisors x =
(init . sort) $
foldr
(\(i, e) a -> (*) <$> a <*> scanl (const . (i *)) 1 [1 .. e])
[1]
((head &&& length) <$> group (primeFactors x))
 
---------------------------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</lang>
{{Out}}
<pre>Proper divisors of [1..10]:
1 -> []
2 -> [1]
3 -> [1]
4 -> [1,2]
5 -> [1]
6 -> [1,2,3]
7 -> [1]
8 -> [1,2,4]
9 -> [1,3]
10 -> [1,2,5]
 
 
A number in the range 1 to 20,000 with the most proper divisors,
9,659

edits