This question already has answers here:
Enumerate factors of a number directly in ascending order without sorting?
(4 answers)
Making a list of divisors without dividing sequentially in Haskell
(3 answers)
Closed 3 years ago.
I want to efficiently find the proper divisors of an integer n.
How can I do this?
For now I´m using the following function
divisors :: (Integral a) => a -> [a]
divisors n = filter ((0 ==) . (n `mod`)) [1 .. (n `div` 2)]
But I have read that it is more efficient when I only check for the numbers until the square root of n. Have you got any suggestions how to solve it with the square root?
Given a number n is dividable by k, then n/k is a divisor of n as well. Indeed, since n/(n/k)=k. If k>√n, we thus know that k/n<√n, and therefore, instead of calculating all the divisors, we can each time we find a divisor, yield the "co-divisor" as well.
We thus can implement the algorithm as follows:
divisors :: Integral a => a -> [a]
divisors n = concatMap f (filter ((==) 0 . mod n) (takeWhile (\k -> k*k <= n) [1 .. n]))
where f k | k < l = [k, l]
| otherwise = [k]
where l = div n k
Here we thus first use takeWhile (\k -> k*k <= n) [1 .. n] to create a list from 1 until (and including if it is integral) √n).
Next we filter these elements, and only retain those that divide n. Finally for each of these elements, we check if the co-divisor is different. If that is the case, we both yield k and the co-divisor l, otherwise (this will only be the case for √n), we only yield k.
For example:
Prelude Data.List> divisors 1425
[1,1425,3,475,5,285,15,95,19,75,25,57]
Related
I need to find all the twin primes up to an inputted number. After my trying it out this is the closest i can get:
primeTwins :: Integer -> [Integer]
primeTwins x = [y | x <- [2..x], y <- [x-2, x+2]]
If x is 20 prime Twins returns: [0,4,1,5,3,7,5,9,9,13,11,15,15,19,17,21]
So this returns primes +2 and primes -2 and with duplicates, However i need just twin primes (A twin prime is a prime number that is either 2 less or 2 more than another prime number) with no duplication. Ive been searching but cant find a way to sort lists. Im very new to haskell, So any help would be appreciated!
First of all, it'd be nice to have an infinite list of primes:
primes :: [Integer]
primes = 2:3:filter
(\n -> not $ any
(\p -> n `mod` p == 0)
(takeWhile (\p -> p * p <= n) primes))
[5,7..]
This is similar to the Sieve of Eratosthenes, checking only prime factors up to the square root of the number. For reference, take 20 primes is [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71], so it works properly. Now, we want to filter out just the twin primes into another infinite list:
infTwinPrimes :: [Integer]
-- we need to manually enter 3 5 7 since 5 is a part of two pairs
infTwinPrimes = 3:5:7:(
-- we convert the tuple into a list
( >>= \(a, b) -> [a, b])
$ filter (\(a, b) -> b - a == 2)
-- we drop 4 to compensate for manually entering 3, 5, 7
$ drop 4
-- we zip primes with its tail in order to
-- get every element in a tuple with the next element
$ zip primes (tail primes)
)
If you're confused, it might help to think about how zip primes (tail primes) is [(2,3),(3,5),(5,7),(7,11),(11,13),(13,17),(17,19),...], and how [(1, 2), (3, 4)] >>= \(a, b) -> [a, b] is [1, 2, 3, 4]. Now, our twin primes function is as easy as a takeWhile:
twinPrimes :: Integer -> [Integer]
twinPrimes n = takeWhile (<= n) infTwinPrimes
And we can verify that it works
λ> twinPrimes 20
[3,5,7,11,13,17,19]
Which does indeed contain every twin prime up to 20.
My goal is to write a function that calculates the maximum Collatz number below a certain number 'n'. (It's a Project Euler question for those who are familiar.)
Some context: A Collatz number for a given integer is equal to the length of the Collatz sequence for that integer. A Collatz sequence for an integer is calculated as follows: the first number ("n0") in the sequence is that integer itself; if n0 is even, the next number in the sequence ("n1") is equal to n / 2; if n0 is odd, then n1 is equal to 3 * n0 + 1. We continue recursively extending the sequence until we arrive at 1, at which point the sequence is finished. For example, the collatz sequence for 5 is: {5, 16, 8, 4, 2, 1} (because 16 = 3 * 5 + 1, 8 = 16 / 2, 4 = 8 / 2,...)
I'm trying to write a function ("maxCollatzUnder") which, when passed an integer "m", returns the integer (less than or equal to m) which has the longest Collatz sequence (i.e., largest Collatz number). For example, maxCollatz 20 (i.e., what integer below (inclusive) 20 has the longest collage sequence?) should return 19 (the number 19 has a Collatz sequence of length 21: [19,58,29,88,44,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1]).
In the code below, the "collatz" and "collatzHelper" functions compile and run correctly. I'm having trouble with the "maxCollatzUnder" function. This function intends to (I) create a list of 2-tuples (x,y) for each integer x ranging from 1 to m (where m is the function argument) and where where y represents the Collatz number for integer x and then (II) look through the list for the highest Collatz number (i.e., y) and return its associated integer (i.e., x)
maxCollatzUnder n = foldl(\acc (i,j) -> if j > acc then i else acc) 0
(zip [1..n] ( map collatzLength [1..n]))
where collatzLength n = length . collatz $ n
collatz n = map truncate $ collatzHelper n
collatzHelper 0 = [0]
collatzHelper 1 = [1]
collatzHelper n
| (truncate n) `mod` 2 == 0 = [n] ++ collatzHelper (n/2)
| otherwise = [n] ++ collatzHelper (3*n+1)
I get the following error when I (attempt to) compile.
*Main> :l PE14Collatz.hs
[1 of 1] Compiling Main ( PE14Collatz.hs, interpreted )
PE14Collatz.hs:7:89:
No instance for (RealFrac Int)
arising from a use of `collatzLength'
In the first argument of `map', namely `collatzLength'
In the second argument of `zip', namely
`(map collatzLength [1 .. n])'
In the third argument of `foldl', namely
`(zip [1 .. n] (map collatzLength [1 .. n]))'
Failed, modules loaded: none.
What's curious is that the code compiles and runs correctly if I change the "maxCollatzUnder" to the following code (see below). The only change is that, in the version below, the fold function returns "j" (i.e., the largest Collatz number) instead of "i" (i.e., the integer which generates the largest Collatz number).
maxCollatzUnder n = foldl(\acc (i,j) -> if j > acc then j else acc) 0
(zip [1..n] ( map collatzLength [1..n]))
where collatzLength n = length . collatz $ n
Suggestions on a more efficient/elegant approach are welcome though I would still be interested in understanding the cause of this error.
Because of your use of truncate (a method of RealFrac) and / (a method of Fractional, a superclass of RealFrac), Haskell infers the following two type signatures for your last two functions:
collatz :: (RealFrac a, Integral b) => a -> [b]
collatzHelper :: RealFrac a => a -> [a]
Haskell then tries to deduce the type of maxCollatzUnder, and its thought process goes like this:
"In collatzLength n = length . collatz $ n, we're passing n to collatz, so the argument to collatzLength must be a RealFrac."
"Therefore, in map collatzLength [1..n], [1..n] must be a list of RealFrac values."
"Therefore, the n in map collatzLength [1..n] must be a RealFrac type."
"Therefore, the n in zip [1..n] (which is the same n) must be a RealFrac type, and so [1..n] is a list of RealFracs."
"Therefore, the i in (\acc (i,j) -> if j > acc then i else acc) must be a RealFrac."
"Because the aforementioned lambda can return either i or acc, they must be the same type."
"Because j is being compared to acc, j must be the same type as acc — and thus the same type as i and a RealFrac."
"But wait— j is the return value from collatzLength, which is the return value of a call to length, and so it has to be an Int, but Int isn't in RealFrac!"
"ERROR! ERROR!"
I have to go now (the Compiler Cabal doesn't like me giving away their secrets), but the shortest fix is to not use truncate and / and just use div for (floored) integer division.
I need to express the sequence of prime numbers. (struggling with ex 3 in project Euler).
I have happened to this recursive definition:
is_not_dividable_by :: (Integral a) => a -> a -> Bool
is_not_dividable_by x y = x `rem` y /= 0
accumulate_and :: (Integral a) => [a] -> (a -> Bool) -> Bool
accumulate_and (x:xs) (f) = (accumulate_and xs (f)) && f(x)
accumulate_and [] f = True
integers = [2,3..]
prime_sequence = [n | n <- integers, is_prime n]
where is_prime n = accumulate_and
(takeWhile (<n) (prime_sequence))
( n `is_not_dividable_by`)
result = take 20 prime_sequence
str_result = show result
main = putStrLn str_result
Though it compiles well, but when executed, it falls into a loop, and just returns <<loop>>
My problem is that I think that I can freely express recursive definitions in Haskell.
But obviously this definition does not fit with the language at all.
However, when I mentally try to solve the prime_sequence, I think I succeed and grow the sequence, but of course with imperative programming apriori.
What is plain wrong in my recursive definition, that makes this code not work in Haskell ?
The culprit is this definition:
prime_sequence = [n | n <- [2,3..], is_prime n] where
is_prime n = accumulate_and
(takeWhile (< n) (prime_sequence))
( n `is_not_dividable_by`)
Trying to find the head element of prime_sequence (the first of the 20 to be printed by your main) leads to takeWhile needing to examine prime_sequence's head element. Which leads to a takeWhile call needing to examine prime_sequence's head element. And so it goes, again and again.
That's the black hole, right away. takeWhile can't even start walking along its input, because nothing's there yet.
This is fixed easily enough by priming the sequence:
prime_sequence = 2 : [n | n <- [3,4..], is_prime n] where
is_prime n = accumulate_and
(takeWhile (< n) (prime_sequence))
( n `is_not_dividable_by`)
Now it gets to work, and hits the second problem, described in Rufflewind's answer: takeWhile can't stop walking along its input. The simplest fix is to stop at n/2. But it is much better to stop at the sqrt:
prime_sequence = 2 : [n | n <- [3,4..], is_prime n] where
is_prime n = accumulate_and
(takeWhile ((<= n).(^ 2)) (prime_sequence))
( n `is_not_dividable_by`)
Now it should work.
The reason it's an infinite loop is because of this line:
prime_sequence =
[n | n <- integers, is_prime n]
where is_prime n = accumulate_and (takeWhile (< n) prime_sequence)
(n `is_not_dividable_by`)
In order to compute is_prime n, it needs to take all the prime numbers less than n. However, in order for takeWhile to know when to stop taking it needs need to also check for n, which hasn't been computed yet.
(In a hand-wavy manner, it means your prime_sequence is too lazy so it ends up biting its own tail and becoming an infinite loop.)
Here's how you can generate an infinite list of prime numbers without running into an infinite loop:
-- | An infinite list of prime numbers in ascending order.
prime_sequence :: [Integer]
prime_sequence = find [] integers
where find :: [Integer] -> [Integer] -> [Integer]
find primes [] = []
find primes (n : remaining)
| is_prime = n : find (n : primes) remaining
| otherwise = find primes remaining
where is_prime = accumulate_and primes (n `is_not_dividable_by`)
The important function here is find, which takes an existing list of primes and a list of remaining integers and produces the next remaining integer that is prime, then delays the remaining computation until later by capturing it with (:).
I'm trying to define an is_prime function in Haskell. Can anyone point out the issue with the use of the any function?
In addition, I know that the below code is naïve, but I am learning the language so starting with babysteps.
is_prime 0 = False
is_prime 1 = False
is_prime 2 = True
is_prime n = any [n `mod` k == 0 | k <- [2.. sqrt n]]
Type of any is (a -> Bool) -> [a] -> Bool, so it accepts a predicate and a collection. So you should rewrite your last case as for instance
is_prime n = not $ any (\k -> n `mod` k /= 0)
[2 .. ceiling $ sqrt $ fromIntegral n]
fromIntegral is necessary because sqrt's type is Floating a => a -> a while your n is an integer. Subsequently, without ceiling the second argument of any would be Floating t => [t]. This would break, as calling mod, whose type is Integral a => a -> a -> a, on non-integral types is illegal.
If you'd like to look for some other implementations, I can recommend for example this discussion.
The accepted answer is, to my mind, incorrect as the is_prime function actually returns False if n is a prime, and here's why.
any function data returns True as soon as it encounters such an element in data that function data is True.
\k -> mod n k /= 0 returns True if applied to a number that does not divide some constant n.
thus, any returns True if there is a number in the given list that does not divide the number n we want to check for primality and False if there is one.
so, is_prime returns True for any number that is divisible by any number in the list [2 .. ceiling $ sqrt $ fromIntegral n], for example, 4 which clearly is not a prime.
With that said, the correct solution should look like this:
is_prime n = not $ any (\k -> n `mod` k == 0) [2 .. ceiling $ sqrt $ fromIntegral n]
This is because a number n is prime if it's not a multiple of any number between 2 and sqrt n.
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.