module Solutions.P38 (highlyTotientNumbers) where
import Data.List (genericLength, genericTake, unfoldr)
import Problems.P35
import Problems.P37
highlyTotientNumbers :: Integral a => [a]
highlyTotientNumbers :: forall a. Integral a => [a]
highlyTotientNumbers = ((a, a) -> Maybe (a, (a, a))) -> (a, a) -> [a]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr (a, a) -> Maybe (a, (a, a))
forall a. Integral a => (a, a) -> Maybe (a, (a, a))
find (a
0,a
0)
find :: Integral a => (a,a) -> Maybe (a,(a,a))
find :: forall a. Integral a => (a, a) -> Maybe (a, (a, a))
find (a
n, a
count) = (a, (a, a)) -> Maybe (a, (a, a))
forall a. a -> Maybe a
Just (a
n', (a
n'a -> a -> a
forall a. Num a => a -> a -> a
+a
1, a
count'))
where (a
n', a
count') = (a, a) -> (a, a)
forall a. Integral a => (a, a) -> (a, a)
next (a
n, a
count)
next :: Integral a => (a,a) -> (a,a)
next :: forall a. Integral a => (a, a) -> (a, a)
next (a
n, a
count) | a
count' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
count = (a
n, a
count')
| Bool
otherwise = (a, a) -> (a, a)
forall a. Integral a => (a, a) -> (a, a)
next (a
na -> a -> a
forall a. Num a => a -> a -> a
+a
1, a
count)
where count' :: a
count' = a -> a
forall a. Integral a => a -> a
tally a
n
tally :: Integral a => a -> a
tally :: forall a. Integral a => a -> a
tally a
n = [a] -> a
forall i a. Num i => [a] -> i
genericLength ([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$ (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter (a
n ==) ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ a -> [a] -> [a]
forall i a. Integral i => i -> [a] -> [a]
genericTake a
bound [a]
forall a. Integral a => [a]
totients
where bound :: a
bound = [a] -> a
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product ([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$ (a -> a) -> [a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (a
1+) ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ a
1 a -> [a] -> [a]
forall a. a -> [a] -> [a]
: a -> [a]
forall a. Integral a => a -> [a]
primeFactors a
n
totients :: Integral a => [a]
totients :: forall a. Integral a => [a]
totients = (a -> a) -> [a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map a -> a
forall a. Integral a => a -> a
totient' [a
1..]