I wish to compute whether a given integer is prime in Haskell:
--primes
isPrime :: (Integral a) => a -> Bool
isPrime n | n < 4 = n > 1
isPrime n = all ((/=0).mod (n-1)) $ 2:3:[x + i | x <- [6,12..s], i <- [-1,1]]
where s = floor $ sqrt $ fromIntegral n
However, running this on the input 131 gives False. I think the error lies in modular arithmetic but I'm not sure. Is there anything wrong with the modular statement in my program?
Related
``
I'm a Haskell newbie and I'm defining a function that given an Int n it tells if a number is prime or not by searching for an 2<=m<=sqrt(n) that mod n m ==0
if such m exists, then n is not prime, if not then n is prime.
I'm trying to define a list with numbers m between 2 and sqrt n, that mod n m ==0
My thought is that if the list is empty then n is prime, it not, n is not prime
`
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
l = [x|x<-[2.. sqrt n], mod n x == 0]
`
But there seems to be a problem with sqrt n when I run my code and I can't understand it. can someone explain what I'm doing wrong/what to change for my code to run/ and why there's an error?
Running the code gives the following error
test.hs:9:28: error:
• No instance for (Floating Int) arising from a use of ‘sqrt’
• In the expression: sqrt n
In the expression: [2 .. sqrt n]
In a stmt of a list comprehension: x <- [2 .. sqrt n]
|
9 | l = [x|x<-[2.. sqrt n], mod n x == 0]
| ^^^^^^
You are correct in saying that the error is with sqrt, but the rest is pretty opaque to a new Haskell developer. Lets try by checking the type of sqrt to see if that helps.
Prelude> :t sqrt
sqrt :: Floating a => a -> a
Here I'm using ghci to interactively write code. :t asks for the type of the preceeding expression. The line sqrt :: Floating a => a -> a says sqrt takes in some floating point number a and returns something of the same type.
Similar to our error message we see this Floating thing. this thing is a typeclass but for the sake of solving this problem we'll save understanding those for later. In essence, haskell is trying to tell you that Int is not floating point number which is what sqrt expects. We can amend that by turning our Int into a Float with fromIntegral which is a really general function for turning number types into one another. (see Get sqrt from Int in Haskell)
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
asFloat :: Float -- new! - tell fromIntegral we want a float
asFloat = fromIntegral n -- new! turn n into a Float
l = [x|x<-[2..sqrt asFloat], mod n x == 0]
This also errors! but it's a new one!
test.hs:10:48: error:
• Couldn't match expected type ‘Int’ with actual type ‘Float’
• In the second argument of ‘mod’, namely ‘x’
In the first argument of ‘(==)’, namely ‘mod n x’
In the expression: mod n x == 0
|
10 | l = [x|x<-[2..sqrt asFloat], mod n x == 0]
| ^
this is saying that x is suddenly a Float. When we changed to [2..sqrt asFloat] we now have made a list of Floats ([Float]). We need to change that back to [Int]. we can do that by calling floor on the result of the square root.
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
asFloat :: Float
asFloat = fromIntegral n
l = [x|x<-[2..floor (sqrt asFloat)], mod n x == 0] -- new! I added floor here to change the result of sqrt from a `Float` into a `Int`
This now correctly compiles.
I have some natural number c. I want to find all pairs of natural numbers a and b, where a < b, such as a * b = c.
I have a solution:
solve c = do solveHelper [1..c] c where
solveHelper xs c = do
x <- xs
(division, modulo ) <- return (c `divMod` x)
True <- return (modulo == 0)
True <- return (x <= division)
return (x, division)
Example:
*Main> solve 10
[(1,10),(2,5)]
Is there a way to accelerate my code, or a better algorithm I should use?
You can do much, much better. The basic idea is this: first, factorize the number; then enumerate the partitions of the factorization. The product of each partition is a solution. There are fast factorization algorithms out there, but even the naive one is quite an improvement on your code; so:
factorize :: Integer -> [Integer]
factorize n
| n < 1 = error "no. =("
| otherwise = go 2 n
where
go p n | p * p > n = [n]
go p n = case quotRem n p of
(q, 0) -> p:go p q
_ -> go (p+1) n
I will use the very nice multiset-comb package to compute partitions of the set of factors. It doesn't support the usual Foldable/Traversable stuff out of the box, so we have to roll our own product operation -- but in fact this can be a bit more efficient than using the product that the standard interface would give us anyway.
import Math.Combinatorics.Multiset
productMS :: Multiset Integer -> Integer
productMS (MS cs) = product [n^p | (n, p) <- cs]
divisors :: Integer -> [(Integer, Integer)]
divisors n =
[ (a, b)
| (aMS, bMS) <- splits (fromList (factorize n))
, let a = productMS aMS; b = productMS bMS
, a <= b
]
For unfair timings, we can compare in ghci:
*Main> :set +s
*Main> length $ solve (product [1..10])
135
(3.55 secs, 2,884,836,952 bytes)
*Main> length $ divisors (product [1..10])
135
(0.00 secs, 4,612,104 bytes)
*Main> length $ solve (product [1..15])
^CInterrupted. [after several minutes, I gave up]
*Main> length $ divisors (product [1..15])
2016
(0.03 secs, 33,823,168 bytes)
Here solve is your solution, divisors is mine. For a fair comparison, we should compile; I used this program:
main = print . last . solve . product $ [1..11]
(And similar with divisors in place of solve.) I compiled with -O2; yours used 1.367s total, mine 0.002s total.
There's one optimization you don't use: you don't have to try every value from 0 to c.
a < b and a * b = c, so a * a < c, meaning you only have to try numbers from 0 to sqrt c. Or, if you don't want to compute the square root of c, you can stop as soon as a * a >= c.
To do so, you can replace [1..c] by (takeWhile (\x -> x * x < c) [1..]).
I'm doing a simple Haskell function using recursion. At the moment, this seems to work but, if I enter 2, it actually comes up as false, which is irritating. I don't think the code is as good as it could be, so, if you have any advice there, that'd be cool too!
I'm pretty new to this language!
EDIT: Ok, so I understand what a prime number is.
For example, I want to be able to check 2, 3, 5, 7, etc and have isPrime return true. And of course if I run the function using 1, 4, 6, 8 etc then it will return false.
So, my thinking is that in pseudo code I would need to do as follows:
num = 2 -> return true
num > 2 && num = even -> return false
After that, I'm struggling to write it down in any working code so the code below is my work in process, but I really suck with Haskell so I'm going nowhere at the minute.
module Recursion where
isPrime :: Int -> Bool
isPrime x = if x > 2 then ((x `mod` (x-1)) /= 0) && not (isPrime (x-1)) else False
Ok,
let's do this step by step:
In math a (natural) number n is prime if it has exactly 2 divisors: 1 and itself (mind 1 is not a prime).
So let's first get all of the divisors of a number:
divisors :: Integer -> [Integer]
divisors n = [ d | d <- [1..n], n `mod` d == 0 ]
then get the count of them:
divisorCount :: Integer -> Int
divisorCount = length . divisors
and voila we have the most naive implementation using just the definition:
isPrime :: Integer -> Bool
isPrime n = divisorCount n == 2
now of course there can be quite some impprovements:
instead check that there is no divisor > 1 and < n
you don't have to check all divisors up to n-1, it's enough to check to the squareroot of n
...
Ok just to give a bit more performant version and make #Jubobs happy ;) here is an alternative:
isPrime :: Integer -> Bool
isPrime n
| n <= 1 = False
| otherwise = not . any divides $ [2..sqrtN]
where divides d = n `mod` d == 0
sqrtN = floor . sqrt $ fromIntegral n
This one will check that there is no divisor between 2 and the squareroot of the number
complete code:
using quickcheck to make sure the two definitions are ok:
module Prime where
import Test.QuickCheck
divisors :: Integer -> [Integer]
divisors n = [ d | d <- [1..n], n `mod` d == 0 ]
divisorCount :: Integer -> Int
divisorCount = length . divisors
isPrime :: Integer -> Bool
isPrime n
| n <= 1 = False
| otherwise = not . any divides $ [2..sqrtN]
where divides d = n `mod` d == 0
sqrtN = floor . sqrt $ fromIntegral n
isPrime' :: Integer -> Bool
isPrime' n = divisorCount n == 2
main :: IO()
main = quickCheck (\n -> isPrime' n == isPrime n)
!!warning!!
I just saw (had something in the back of my mind), that the way I did sqrtN is not the best way to do it - sorry for that. I think for the examples with small numbers here it will be no problem, but maybe you really want to use something like this (right from the link):
(^!) :: Num a => a -> Int -> a
(^!) x n = x^n
squareRoot :: Integer -> Integer
squareRoot 0 = 0
squareRoot 1 = 1
squareRoot n =
let twopows = iterate (^!2) 2
(lowerRoot, lowerN) =
last $ takeWhile ((n>=) . snd) $ zip (1:twopows) twopows
newtonStep x = div (x + div n x) 2
iters = iterate newtonStep (squareRoot (div n lowerN) * lowerRoot)
isRoot r = r^!2 <= n && n < (r+1)^!2
in head $ dropWhile (not . isRoot) iters
but this seems a bit heavy for the question on hand so I just remark it here.
Here are two facts about prime numbers.
The first prime number is 2.
An integer larger than 2 is prime iff it's not divisible by any prime number up to its square root.
This knowledge should naturally lead you to something like the following approach:
-- primes : the infinite list of prime numbers
primes :: [Integer]
primes = 2 : filter isPrime [3,5..]
-- isPrime n : is positive integer 'n' a prime number?
isPrime :: Integer -> Bool
isPrime n
| n < 2 = False
| otherwise = all (\p -> n `mod` p /= 0) (primesPrefix n)
where primesPrefix n = takeWhile (\p -> p * p <= n) primes
As a bonus, here is a function to test whether all items of a list of integers be prime numbers.
-- arePrimes ns : are all integers in list 'ns' prime numbers?
arePrimes :: [Integer] -> Bool
arePrimes = all isPrime
Some examples in ghci:
ghci> isPrime 3
True
ghci> isPrime 99
False
ghci> arePrimes [2,3,7]
True
ghci> arePrimes [2,3,4,7]
False
You can get a recursive formulation from the "2 divisors" variant by step-wise refinement:
isPrime n
= 2 == length [ d | d <- [1..n], rem n d == 0 ]
= n > 1 && null [ d | d <- [2..n-1], rem n d == 0 ]
= n > 1 && and [ rem n d > 0 | d <- takeWhile ((<= n).(^2)) [2..] ]
= n > 1 && g 2
where
g d = d^2 > n || (rem n d > 0 && g (d+1))
= n == 2 || (n > 2 && rem n 2 > 0 && g 3)
where
g d = d^2 > n || (rem n d > 0 && g (d+2))
And that's your recursive function. Convince yourself of each step's validity.
Of course after we've checked the division by 2, there's no need to try dividing by 4,6,8, etc.; that's the reason for the last transformation, to check by odds only. But really we need to check the divisibility by primes only.
I'm trying to make function primes which is a list of prime numbers, but somehow I have failed. The compiler throws an error I don't know how to resolve:
Error:
Ambiguous type variable 'a0'
Code:
candidates :: [Integer]
candidates = [2]++[3,5..]
primes :: [Integer]
primes = filter is_prime candidates
is_prime :: Integer -> Bool
is_prime candidate
| candidate == 1 = False
| candidate == 2 = True
| candidate == 3 = True
| otherwise = r_is_prime candidate 0
-- r as recursive
r_is_prime :: Integer -> Integer -> Bool
r_is_prime candidate order
| n_th_prime >= max_compared_prime = True
| candidate `mod` n_th_prime == 0 = False
| otherwise = if (r_is_prime candidate (order+1) ) then True else False
where
n_th_prime = candidates !! fromIntegral(order)
-- this is the line that throws an error...
max_compared_prime = fromIntegral ( ceiling ( fromIntegral ( sqrt ( fromIntegral candidate))))
In
max_compared_prime = fromIntegral ( ceiling ( fromIntegral ( sqrt ( fromIntegral candidate))))
you have a fromIntegral too much. sqrt has type
sqrt :: Floating a => a -> a
so the result of sqrt is not a member of an Integral type. And the result of ceiling is an Integral type, so the last fromIntegral is superfluous (but does not harm).
max_compared_prime = ceiling ( sqrt ( fromIntegral candidate))
is all you need in that line.
Note, however, that
n_th_prime = candidates !! fromIntegral(order)
means that to test against the n-th candidate prime, the list of candidates has to be traversed until the n-th prime has been reached. Thus testing against the n-th candidate is O(n) here instead of O(1) [Well, assuming that numbers are bounded] which a single division is.
A more efficient trial division only tries primes for the division and remembers where in the list of primes it was when it goes on to the next prime. For example
is_prime :: Integer -> Bool
is_prime n
| n < 2 = False
| n < 4 = True
| otherwise = trialDivision primes
where
r = floor (sqrt $ fromIntegral n)
trialDivision (p:ps)
| r < p = True
| otherwise = n `rem` p /= 0 && trialDivision ps
Just traverses the list of primes in order to do the trial division, hence going from one prime to the next is a simple step in the list.
You have too many fromIntegrals in
max_compared_prime = fromIntegral ( ceiling ( fromIntegral ( sqrt ( fromIntegral candidate))))
The fromIntegral applied to the result of sqrt is causing the error. If we look at the type signatures, we have:
fromIntegral :: (Num b, Integral a) => a -> b
sqrt :: Floating a => a -> a
So to properly infer the type of fromIntegral (sqrt x) Haskell needs to find a type with both Floating and Integral instances (so that the result of sqrt matches the parameter of fromIntegral). Haskell can't find such a type and so (basically) is asking you to specify one (but there isn't one). The solution is to just elide this fromIntegral:
max_compared_prime = fromIntegral ( ceiling ( sqrt ( fromIntegral candidate)))
other notes
Brackets aren't particularly idiomatic Haskell, so that line can/should be written as:
max_compared_prime = fromIntegral . ceiling . sqrt . fromIntegral $ candidate
Furthermore, the result of ceiling doesn't need to be converted, so it can even be:
max_compared_prime = ceiling . sqrt . fromIntegral $ candidate
Remove 'fromIntegral' from before 'sqrt', as:
max_compared_prime = fromIntegral ( ceiling ( sqrt ( fromIntegral candidate)))
The types are:
sqrt :: Floating a => a -> a
fromIntegral :: (Integral a, Num b) => a -> b
the output of sqrt is 'Floating', not Integral.
I'm working through Project Euler, and a lot of problems involve similar functions, for example calculating lists of primes. I know calculations with Integer are slower than Int so I'd like to write the functions to work with both, depending on the size of the numbers I'm working with.
module Primes
(
isPrime
,prime
,allPrimes
)
where
import Data.List
isPrime :: Int -> Bool
isPrime n
| n == 0 = False
| n == 1 = False
| n < 0 = isPrime (-n)
| n < 4 = True
| n `mod` 2 == 0 = False
| n `mod` 3 == 0 = False
| any ( (==0) . mod n ) [5..h] = False
| otherwise = True
where
h = ( ceiling . sqrt . fromIntegral ) n
allPrimes :: [Int]
allPrimes = [ x | x<- [2..], isPrime x ]
prime :: Int -> Int
prime n = allPrimes !! (n-1)
I know this code isn't generally as optimal as it could be. I'm just interested in how to make the integer types more generic.
Try Integral it should allow support for both Int and Integer
A more general solution to this kind of problem, you could try getting your code to compile without the explicit type declarations. Haskell will assume the most general type possible and you can find out what it was by, for example, loading your file on GHCi and doing a :t myFunctionName