import Numeric.Combinatorics
import Numeric.Integer
import Numeric.NumberTheory
import Numeric.Pure
import Test.Hspec
import Test.Hspec.QuickCheck
tooBig :: Int -> Int -> Bool
tooBig x y = go x y >= 2 ^ (16 :: Integer)
where
go :: Int -> Int -> Integer
go m n = fromIntegral m ^ (fromIntegral n :: Integer)
main :: IO ()
main = hspec $ parallel $ do
describe "isPrime" $
prop "should agree with the pure Haskell function" $
\x -> x < 1 || isPrime x == hsIsPrime x
describe "totient" $
prop "should agree with the pure Haskell function" $
\m -> m < 1 || totient m == hsTotient m
describe "totient" $
prop "should be equal to m-1 for m prime" $
\m -> m < 1 || not (isPrime m) || totient m == m - 1
describe "totient" $
prop "should satisfy Fermat's little theorem" $
\a m -> a < 1 || m < 2 || gcd a m /= 1 || tooBig a m || (a ^ totient m) `mod` m == 1
describe "tau" $
prop "should agree with the pure Haskell function" $
\n -> n < 1 || tau n == hsTau n
describe "littleOmega" $
prop "should agree with the pure Haskell function" $
\n -> n < 1 || littleOmega n == hsLittleOmega n
describe "isPerfect" $
prop "should agree with the pure Haskell function" $
\n -> n < 1 || isPerfect n == hsIsPerfect n
describe "factorial" $
it "should work on a slightly large number" $
factorial 3141 >>= (`shouldBe` hsFactorial 3141)