I'm having an issue with a simple Haskell program. It's supposed to factor a number n-1 into the form (2^r)s where n is a Carmichael number. This isn't really pertinent to my question, but it's what the following set of functions aims to do.
divides::Int->Int->Bool
divides x y = not $ y `mod` x == 0
carmichaeltwos::Int->Int
carmichaeltwos n
| not $ divides 2 n =0
| otherwise = (+ 1) $ carmichaeltwos (n/2)
carmichaelodd::Int->Int
carmichaelodd n
| not $ divides 2 n = n
| otherwise = carmichaelodd (n/2)
factorcarmichael::Int->(Int, Int)
factorcarmichael n = (r, s)
where
nminus = n-1
r = carmichaeltwos nminus
s = carmichaelodd nminus
When I try to load this into GHCi, Haskell spits up:
No instance for (Fractional Int)
arising from a use of `/'
Possible fix: add an instance declaration for (Fractional Int)
In the first argument of `carmichaelodd', namely `(n / 2)'
In the expression: carmichaelodd (n / 2)
In an equation for `carmichaelodd':
carmichaelodd n
| not $ divides 2 n = n
| otherwise = carmichaelodd (n / 2)
I know that the function / has type (/)::(Fractional a)=>a->a->a, but I don't see how to fix my program to make this work nicely.
Also, I realize that I'm basically computing the same thing twice in the factorcarmichael function. I couldn't think of any easy way to factor the number in one pass and get the tuple I want as an answer.
To divide two Ints when you know, as in this case, that the dividend is divisible by the divisor, use the div or quot function, i.e., div n 2 or quot n 2. (div and quot differ only in their handling of negative operands when the "true" quotient isn't an integer.)
Also, why are you defining divides as not $ mod y x == 0? Unless you're using a nonstandard meaning of "divides," you should be using just mod y x == 0 — x divides y iff y modulo x is zero.
As for combining carmichaeltwos and carmichaelodd, try using the until function:
factorcarmichael n = until (\(_, s) -> not $ divides 2 s)
(\(r, s) -> (r+1, div s 2))
(0, n-1)
Related
I recently started learning Haskell. To train a bit I wanted to try generating the list of prime numbers via self reference using the following code:
main = do
print (smaller_than_sqrt 4 2)
print (smaller_than_sqrt_list 5 [2..])
print ("5")
print (is_prime 5 [2..])
print ("7")
print (is_prime 7 [2..])
print ("9")
print (is_prime 9 [2..])
print ("test")
print (take 5 primes) -- Hangs
-- Integer square root
isqrt :: Int -> Int
isqrt = ceiling . sqrt . fromIntegral
-- Checks if x is smaller than sqrt(p)
smaller_than_sqrt :: Int -> Int -> Bool
smaller_than_sqrt p x = x <= isqrt p
-- Checks if x doesn't divide p
not_divides :: Int -> Int -> Bool
not_divides p x = p `mod` x /= 0
-- Takes in a number and an ordered list of numbers and only keeps the one smaller than sqrt(p)
smaller_than_sqrt_list :: Int -> [Int] -> [Int]
smaller_than_sqrt_list p xs = takeWhile (smaller_than_sqrt p) xs
-- Checks if p is prime by looking at the provided list of numbers and checking that none divides p
is_prime :: Int -> [Int] -> Bool
is_prime p xs = all (not_divides p) (smaller_than_sqrt_list p xs)
-- Works fine: primes = 2 : [ p | p <- [3..], is_prime p [2..]]
-- Doesn't work:
primes = 2 : 3 : [ p | p <- [5..], is_prime p primes]
But for some reason referencing primes inside of primes hangs when running runhaskell and is detected as a loop error when running the compiled binary with ghc.
However I don't really understand why.
Clearly, the first two elements of primes are 2 and 3. What comes after that? The next element of primes is the first element of
[p | p <- [5..], is_prime p primes]
What's that? It could be 5, if is_prime 5 primes, or it could be some larger number. To find out which, we need to evaluate
smaller_than_sqrt_list 5 primes
Which requires
takeWhile (<= isqrt 5) primes
Which requires
takeWhile (<= 3) primes
Well, that's easy enough, it starts with 2:3:..., right? Okay, but what's the next element? We need to look at the third element of primes and see whether it's less or equal to 3. But the third element of primes is what we were trying to calculate to begin with!
The problem is that smaller_than_sqrt 5 3 is still True. To compute whether 5 is a prime, the is_prime 5 primes expands to all (not_divides 5) (takeWhile (smaller_than_sqrt 5) primes), and takeWhile will attempt to iterate primes until the predicate no longer holds. It does hold for the first element (2), it still does hold for the second element (3), will it hold for the next element - wait what's the next element? We're still computing which one that is!
It should be sufficient to use floor instead of ceiling in isqrt, or simpler just
smaller_than_sqrt p x = x * x <= p
I have been trying to learn haskell by trying to do some simple problems.
The Problem
Currently, I am trying to implement a function primeFactorization :: Integer -> [(Integer, Integer)] such that the output is a list of tuples containing the prime factor and the power it is raise to in the number.
Example Output
> primeFactorization 120
[(2,3), (3,1), (5,1)] since 120 = 2^3 * 3^1 * 5^1
My (Partial) Solution
primeFactorization :: Integer -> [Integer]
primeFactorization n =
let
factors :: Integer -> [Integer]
factors n = [x | x <- [2..n-1], n `mod` x == 0]
isPrime :: Integer -> Bool
isPrime n
| n `elem` [0, 1] = False
| n == 2 = True
| n > 2 = null [ x | x <- [2..(ceiling . sqrt . fromIntegral) n], n `mod` x == 0]
| otherwise = False
in
filter isPrime $ (factors n)
This is a working implementation to get the prime factors of a number. However as seen it only outputs the prime factors. I am not sure on how to store the number of times in haskell. Also, considering it is un-idiomatic to iterate in haskell I don't know how I would implement the solution. In python, I would do:
def pf(number):
factors=[]
d=2
while(number>1):
while(number%d==0):
factors.append(d)
number=number/d
d+=1
return factors
So, the question: How to implement the powers of the prime factors?
NOTE:
I already saw: Prime factorization of a factorial however that does not answer my question.
This is NOT a homework problem, I am learning independently.
You can always replace imperative-language loops (as long as they don't meddle with any global state) with recursion. That may not be the most elegant approach, but in this case it seems perfectly appropriate to imitate your inner Python loop with a recursive function:
dividerPower :: Integer -> Integer -> Int
dividerPower n d
| n`rem`d == 0 = 1 + dividerPower (n`quot`d) d
| otherwise = 0
(This counts “backwards” compared to the Python loop. You could also make it tail-recursive with a helper function and count forwards over an accumulator variable, but that's more awkward and I don't think there's a memory/performance benefit that would justify it in this case.)
You can either use that together with your Haskell code (for each of the factors you've already found, check how often it occurs), or extend it so the whole thing works like the Python solution (which is actually a lot more efficient, because it avoids for every number checking whether it's prime). For that you just need to give back the final n in the result. Let's use a where block for handling the pattern matching, and also make the rem and:
dividePower :: Integer -> Integer -> (Integer, Int)
dividePower n d
| r == 0 = (nfin, p'+1)
| otherwise = (n, 0)
where (n', r) = n `quotRem` d
(nfin, p') = dividePower n' d
Then the equivalent to your Python code is
pf :: Integer -> Integer -> [(Integer, Int)]
pf = go 2
where go d n
| n>1 = (d, p) : go (d+1) n'
| otherwise = []
where (n', p) = dividePower n d
This actually gives you, like in Python, the list including also non-dividers (with power 0). To avoid that, change the list-building to
| n>1 = (if p>0 then ((d,p):) else id) $ go (d+1) n'
digits :: Int -> [Int]
digits n = reverse (x)
where x
| n < 10 = [n]
| otherwise = (mod n 10) : (digits (div n 10))
*ghci> digits 1234 = [3,1,2,4]*
digits' :: Int -> [Int]
digits' n = (x)
where x
| n < 10 = [n]
| otherwise = (mod n 10) : (digits' (div n 10))
*ghci>digits' 1234 = [4,3,2,1]*
As per my understanding the evaluation of digits 1234 should be [1,2,3,4]. But it seems that I am missing something. Can anyone explain this?
The problem is that digits reverses the string in each recursive call, not just once at the outer level. Try digits x = reverse (digits' x) (or, equivalently, digits = reverse . digits'), and see if you can explain the difference.
Notwithstanding the excellent answer by amalloy, here is a way of getting the digits in the expected order without involving the reverse library function.
We use the common trick of accumulating the result in some extra argument of the recursive call, (the “accumulator”) noted here as dgs.
We also use the divMod library function, which returns a pair containing both the quotient and the remainder.
digits :: Int -> [Int]
digits n = go [] n
where
base = 10
go dgs k = if (k < base) then (k:dgs)
else let (q,r) = divMod k base
in go (r:dgs) q
The accumulator grows by successive prepending operations, in such a way that the digits end up in the appropriate order.
I want to list all integers that divide n. This is a homework question. So far I have done this.
divisors :: Int -> [Int]
divisors n | n < 1 = []
| otherwise = filter (\n -> n `mod` x == 0) [1..n]
where x = [1..n]
I know this is wrong, but I am not getting the right filter predicate. I don't know how the syntax is for doing this. and ofcourse I cannot use n mod n since that is just lists all elements 1 to n.
You want to check if mod n k == 0 for each k from 1 to n. The n is fixed (the argument of divisors) and the k varies, i.e. that is what should be the argument of the lambda expression
| otherwise = filter (\k -> n `mod` k == 0) [1 .. n]
I don't know what you are trying to do, but the type of mod is
mod :: Integral a => a -> a -> a
You call it with an Integral argument and a list of integral arguments.
I'm new to Haskell, and I'm trying a bit:
isPrime :: Integer->Bool
isPrime x = ([] == [y | y<-[2..floor (sqrt x)], mod x y == 0])
I have a few questions.
Why when I try to load the .hs, WinHugs say: Instances of (Floating Integer, RealFrac Integer) required for definition of isPrime?
When the interpreter finds one element in the right set, it immediately stops or it computes all the set? I think you know what I mean.
Sorry about my english.
1) The problem is that sqrt has the type (Floating a) => a -> a, but you try to use an Integer as argument. So you have to convert your Integer first to a Floating, e.g. by writing sqrt (fromIntegral x)
2) I see no reason why == shouldn't be lazy, but for testing for an empty collection you can use the null function (which is definitely lazy, as it works on infinite lists):
isPrime :: Integer->Bool
isPrime x = null [y | y<-[2..floor (sqrt (fromIntegral x))], x `mod` y == 0]
But in order to get an more idiomatic solution, break the problem into smaller sub-problems. First, we need a list of all elements y with y*y <= x:
takeWhile (\y -> y*y <= x) [2..]
Then we need only the elements that divide x:
filter (\y -> x `mod`y == 0) (takeWhile (\y -> y*y <= x) [2..])
Then we need to check if that list is empty:
isPrime x = null (filter (\y -> x `mod`y == 0) (takeWhile (\y -> y*y <= x) [2..]))
And if this looks to lispy to you, replace some of the parens with $
isPrime x = null $ filter (\y -> x `mod` y == 0) $ takeWhile (\y -> y*y <= x) [2..]
For additional clarity you can "outsource" the lambdas:
isPrime x = null $ filter divisible $ takeWhile notTooBig [2..] where
divisible y = x `mod`y == 0
notTooBig y = y*y <= x
You can make it almost "human readable" by replacing null $ filter with not $ any:
isPrime x = not $ any divisible $ takeWhile notTooBig [2..] where
divisible y = x `mod`y == 0
notTooBig y = y*y <= x
Because sqrt has the type Floating a => a -> a. This means the input has to be a Floating type and the output will be the same type. In other words x needs to be a Floating type. However you declared x to be of type Integer, which is not a Floating type. In addition floor needs a RealFrac type, so x needs to be that as well.
The error message suggests that you fix that by making Integer a Floating type (by defining an instance Floating Integer (and the same for RealFrac).
Of course this is not the correct approach in this case. Rather you should use fromIntegral to convert x to a Real (which is an instance of Floating and RealFrac) and then give that to sqrt.
Yes. As soon as == sees that the right operand has at least one element, it knows it is not equal to [] and thus returns False.
That being said, null is a more idiomatic way to check whether a list is empty than [] ==.
Regarding the second point, it stops, for example:
[] == [x | x <- [1..]]
Returns False
Landei's solution is great, however, if you want a more efficient¹ implementation we have (thanks to BMeph):
-- list of all primes
primes :: [Integer]
primes = sieve (2 : 3 : possible [1..]) where
sieve (p : xs) = p : sieve [x | x <- xs, x `mod` p > 0]
possible (x:xs) = 6*x-1 : 6*x+1 : possible xs
isPrime :: Integer -> Bool
isPrime n = shortCircuit || (not $ any divisible $ takeWhile inRangeOf primes) where
shortCircuit = elem n [2,3] || (n < 25 && ((n-1) `mod` 6 == 0 || (n+1) `mod` 6 == 0))
divisible y = n `mod` y == 0
inRangeOf y = y * y <= n
The 'efficiency' comes from the use of constant primes. It improves the search in two ways:
The Haskell runtime could cache the results so subsequent invocations are not evaluated
It eliminates a range of numbers by logic
note that the sieve value is simply a recursive table, where says the head of
the list is prime, and adds it to it. For the rest of the lists if there is no
other value already in the list that composes the number then its also prime
possible is list of all possible primes, since all possible primes are in the
form 6*k-1 or 6*k-1 except 2 and 3
The same rule is applied for shortCircuit too to quickly bail out of calculations
Footnote by D.F.
¹ It's still a terribly inefficient way to find primes. Don't use trial division if you need primes larger than a few thousand, use a sieve instead. There are several far more efficient implementations on hackage.
I think WinHugs needs to import a module for Integer and etc... Try Int
The interpreter will not compute anything until you call e.g. isPrime 32 then it will lazily compute the expression.
PS your isPrime implementation is not the best implementation!