This question already has answers here:
Sum of Squares using Haskell
(3 answers)
Closed 8 years ago.
Ok This is a homework question but I'm not asking for a solution to how its done
What I want to ask is what it is asking me to do?
The sum of the squares of integers in the range m:n (where m ≥ n) can
be computed recursively. If there is more than one number in the range
m:n, the solution is to add the square of m to the sum of the squares
in the rangem+1:n; otherwise there is only one number in the range
m:n, so m == n, and the solution is just the square of m.
a. Define the recursive function sumsquares to carry out this
computation. As always, draw up a series of test data showing the
expected output, and then test the function.
I know I have to write a recursive function called sumsquares but I dont quite understand what it means by "The sum of the squares of integers in the range m:n (where m ≥ n) can be computed recursively".
This is the code I have so far, Would this be correct??
sumsquares :: Integral a=> Int -> Int -> Int
sumsquares m n
|m > n = error "First number cannot be bigger than second number"
|m==n = m*n
|otherwise = m*n +sumsquares (m+1)n
Someone else came up with this answer
sumOfSquaresFast :: Integral a => a -> a -> a
sumOfSquaresFast lo hi
| lo > hi = error "sumOfSquaresFast: lo > hi"
| otherwise = ssq hi - ssq (lo - 1)
where ssq x = div (2 * x^3 + 3 * x^2 + x) 6
But I do not understand the bottom part, the ssq and the div functions?
From what I understand, you want to take two numbers, e.g. 1 and 10, square each number between them (inclusively), and then take the sum of that. So you'd want some function like
sumOfSquaresBetween :: Int -> Int -> Int
sumOfSquaresBetween m n = ???
Now, you have to use recursion, so this means that ??? is going to be some expression that uses sumOfSquaresBetween.
Now here's the trick: If you know sumOfSquares n n, then how would you find sumOfSquares (n - 1) n? What about sumOfSquares (n - 2) n? Can you generalize this all the way to sumOfSquares m n for m <= n? If so, then you've just performed your desired algorithm, but in reverse.
Hope this hint helps.
"The sum of the squares of integers in the range m:n (where m ≥n) can be computed recursively."
Let's break this apart....
"integers in the range m:n"
is the set of integers starting from m, going to n
[m, m+1, m+2, ....n]
ie-
integers in the range 4:8 = [4,5,6,7,8]
"squares of...."
As you probably know, the square of a number x is x*x, so
squares of integers in the range 4:8 = [16, 26, 36, 49, 64]
"The sum of...."
add them
The sum of the squares of integers in the range 4:8 = 16+26+36+49+64
".... can be computer recursively"
Well, you have to understand recursion to get this....
Any function that contains itself in the definition is recursive. Of course you have to be careful, if done incorrectly, a recursive function could lead to infinite loops....
For Ints, (N-1) recursion is common.... If you can use the calculation for (N-1) to evaluate the calculation for N, the computer can run down the numbers until a known value is hit (typically 0). This is better seen with an example.
let func n = sum of integers from 0 to n
(this is like your problem, but without the squares part)
if you know the value of func (n-1), you can easily compute the value of func n
func n = n + func (n-1)
func 0 = 0
The computer will use func 0 to compute func 1, func 1 to compute func 2, etc, all the way to N.
Recursion has two common (but actually pretty different) uses... First, as shown above, it allows for very clean function definitions.
Secondly, it is often used in mathematics to prove truths over all integers (ie- to prove something is true for all ints, prove it is true for 0, then prove if it is true for N, it is true for N+1....).
Really, the best way to solve this problem is also the easiest: use library functions.
sumsquares :: Integral a => a -> a -> a
sumsquares m n = sum (map (^2) (enumFromTo n m))
You just enumerate the numbers from n to m, square each of them, and take the sum of the results. Trying to solve this problem in with direct recursion just makes things needlessly complicated.
Exercise: Write your own versions of the library functions used in this answer.
-- | Generate the list of all values in the given range. Result is inclusive.
enumFromTo :: Enum a => a -> a -> [a]
-- | Apply a function individually to each element of the argument list,
-- and collect the results as a list, respecting the order of the original.
map :: (a -> b) -> [a] -> [b]
-- | Calculate the sum of a list of numbers.
sum :: Num a => [a] -> a
I've just started learning a bit of Haskell and functional programming, but I find it very difficult getting a hang of it :)
I am trying to translate a small piece of ruby code to Haskell (because I like the concept functional programming and Haskell proposes and even more because I come from a mathematics field and Haskell seems very mathematical):
class Integer
def factorial
f = 1; for i in 1..self; f *= i; end; f
end
end
boundary = 1000
m = 0
# Brown Numbers - pair of integers (m,n) where n factorial is equal with square root of m
while m <= boundary
n = 0
while n <= boundary
puts "(#{m},#{n})" if ((n.factorial + 1) == (m ** 2))
n += 1
end
m += 1
end
I could only figure out how to do factorials:
let factorial n = product [1..n]
I cannot figure out how to do the while loops or equivalent in Haskell, even though I found some examples that were far to confusing for me.
The idea is that the loops start from 0 (or 1) and continue (with an increment of 1) until it reaches a boundary (in my code is 1000). The reason there is a boundary is because I was thinking of starting parallel tasks that do the same operation but on different intervals so the results that I expect are returned faster (one operation would be done on 1 to 10000, another on 10000 to 100000, etc.).
I would really appreciate it if anyone could help out with this :)
Try this:
let results = [(x,y) | x <- [1..1000], y <- [1..1000] ,1 + fac x == y*y]
where fac n = product [1..n]
This is a list comprehension. More on that here.
To map it to your Ruby code,
The nested loops in m and n are replaced with x and y. Basically there is iteration over the values of x and y in the specified ranges (1 to 1000 inclusive in this case).
The check at the end is your filter condition for getting Brown numbers.
where allows us to create a helper function to calculate the factorial.
Note that instead of a separate function, we could have computed the factorial in place, like so:
(1 + product[1..x]) == y * y
Ultimately, the (x,y) on the left side means that it returns a list of tuples (x,y) which are your Brown numbers.
OK, this should work in your .hs file:
results :: [(Integer, Integer)] --Use instead of `Int` to fix overflow issue
results = [(x,y) | x <- [1..1000], y <- [1..1000] , fac x == y*y]
where fac n = product [1..n]
To add to shree.pat18's answer, maybe an exercise you could try is to translate the Haskell solution back into Ruby. It should be possible, because Ruby has ranges, Enumerator::Lazy and Enumerable#flat_map. The following rewritten Haskell solution should perhaps help:
import Data.List (concatMap)
results :: [(Integer, Integer)]
results = concatMap (\x -> concatMap (\y -> test x y) [1..1000]) [1..1000]
where test x y = if fac x == y*y then [(x,y)] else []
fac n = product [1..n]
Note that Haskell concatMap is more or less the same as Ruby Enumerable#flat_map.
I'm new to Haskell and tinkering around with the Euler Project problems. My solution for problem #3 is far too slow. At first I tried this:
-- Problem 3
-- The prime factors of 13195 are 5, 7, 13 and 29.
-- What is the largest prime factor of the number 600851475143 ?
problem3 = max [ x | x <- [1..n], (mod n x) == 0, n /= x]
where n = 600851475143
Then I changed it to return all x and not just the largest one.
problem3 = [ x | x <- [1..n], (mod n x) == 0, n /= x]
where n = 600851475143
After 30 minutes, the list is still being processed and the output looks like this
[1,71,839,1471,6857,59569,104441,486847,1234169,5753023,10086647,87625999,408464633,716151937
Why is it so slow? Am I doing something terribly wrong or is it normal for this sort of task?
With your solution, there are about 600 billion possible numbers. As noted by delnan, making every check of the number quicker is not going to make much difference, we must limit the number of candidates.
Your solution does not seem to be correct either. 59569 = 71 * 839 isn't it? The question
only asks for prime factors. Notice that 71 and 839 is in your list so you are
doing something right. In fact, you are trying to find all factors.
I think the most dramatic effect you get simply by dividing away the factor before continuing.
euler3 = go 2 600851475143
where
go cand num
| cand == num = [num]
| cand `isFactorOf` num = cand : go cand (num `div` cand)
| otherwise = go (cand + 1) num
isFactorOf a b = b `mod` a == 0
This may seem like an obvious optimization but it relies on the fact that if both a and b divides c and a is coprime to b then a divides c/b.
If you want to do more, the common "Only check until the square root" trick has been
mentioned here. The same trick can be applied to this problem, but the performance gain does not show, unfortunately, on this instance:
euler3 = go 2 600851475143
where
go cand num
| cand*cand > num = [num]
| cand `isFactorOf` num = cand : go cand (num `div` cand)
| otherwise = go (cand + 1) num
isFactorOf a b = b `mod` a == 0
Here, when a candidate is larger than the square root of the remaining number (num), we know that num must be a prime and therefore a prime factor of the original
number (600851475143).
It is possible to remove even more candidates by only considering prime numbers,
but this is slightly more advanced because you need to make a reasonably performant
way of generating primes. See this page for ways of doing that.
It's doing a lot of work! (It's also going to give you the wrong answer, but that's a separate issue!)
There are a few very quick ways you could speed it up by thinking about the problem a little first:
You are applying your function over all numbers 1..n, and checking each one of them to ensure it isn't n. Instead, you could just go over all numbers 1..n-1 and skip out n different checks (small though they are).
The answer is odd, so you can very quickly filter out any even numbers by going from 1..(n-1)/2 and checking for 2x instead of x.
If you think about it, all factors occur in pairs, so you can in fact just search from 1..sqrt(n) (or 1..sqrt(n)/2 if you ignore even numbers) and output pairs of numbers in each step.
Not related to the performance of this function, but it's worth noting that what you've implemented here will find all of the factors of a number, whereas what you want is only the largest prime factor. So either you have to test each of your divisors for primality (which is going to be slow, again) or you can implement the two in one step. You probably want to look at 'sieves', the most simple being the Sieve of Eratosthenes, and how you can implement them.
A complete factorization of a number can take a long time for big numbers. For Project Euler problems, a brute force solution (which this is) is usually not enough to find the answer in your lifetime.
Hint: you do not need to find all prime factors, just the biggest one.
TL;DR: The two things you were doing non-optimally, are: not stopping at the square root, and not dividing out each smallest factor, as they are found.
Here's a little derivation of the (2nd) factorization code shown in the answer by HaskellElephant. We start with your code:
f1 n = [ x | x <- [2..n], rem n x == 0]
n3 = 600851475143
Prelude> f1 n3
[71,839,1471,6857,59569,104441,486847Interrupted.
So it doesn't finish in any reasonable amount of time, and some of the numbers it produces are not prime... But instead of adding primality check to the list comprehension, let's notice that 71 is prime. The first number produced by f1 n is the smallest divisor of n, and thus it is prime. If it weren't, we'd find its smallest divisor first - a contradiction.
So, we can divide it out, and continue searching for the prime factors of newly reduced number:
f2 n = tail $ iterate (\(_,m)-> (\f->(f, quot m f)) . head $ f1 m) (1,n)
Prelude> f2 n3
[(71,8462696833),(839,10086647),(1471,6857),(6857,1),(*** Exception: Prelude.hea
d: empty list
(the error, because f1 1 == []). We're done! (6857 is the answer, here...). Let's wrap it up:
takeUntil p xs = foldr (\x r -> if p x then [x] else x:r) [] xs
pfactors1 n = map fst . takeUntil ((==1).snd) . f2 $ n -- prime factors of n
Trying out our newly minted solution,
Prelude> map pfactors1 [n3..]
[[71,839,1471,6857],[2,2,2,3,3,1259Interrupted.
suddenly we hit a new inefficiency wall, on numbers without small divisors. But if n = a*b and 1 < a <= b, then a*a <= a*b == n and so it is enough to test only until the square root of a number, to find its smallest divisor.
f12 n = [ x | x <- takeWhile ((<= n).(^2)) [2..n], rem n x == 0] ++ [n]
f22 n = tail $ iterate (\(_,m)-> (\f->(f, quot m f)) . head $ f12 m) (1,n)
pfactors2 n = map fst . takeUntil ((==1).snd) . f22 $ n
What couldn't finish in half an hour now finishes in under one second (on a typical performant box):
Prelude> f12 n3
[71,839,1471,6857,59569,104441,486847,600851475143]
All the divisors above sqrt n3 were not needed at all. We unconditionally add n itself as the last divisor in f12 so it is able to handle prime numbers:
Prelude> f12 (n3+6)
[600851475149]
Since n3 / sqrt n3 = sqrt n3 ~= 775146, your original attempt at f1 n3 should have taken about a week to finish. That's how important this optimization is, of stopping at the square root.
Prelude> f22 n3
[(71,8462696833),(839,10086647),(1471,6857),(6857,1),(1,1),(1,1),(1,1),(1,1),(1,
1),(1,1),(1,1),(1,1),(1,1),(1,1),(1,1),(1,1),(1,1),(1,1)Interrupted
We've apparently traded the "Prelude.head: empty list" error for a non-terminating - but productive - behavior.
Lastly, we break f22 up in two parts and fuse them each into the other functions, for a somewhat simplified code. Also, we won't start over anew, as f12 does, searching for the smallest divisor from 2 all the time, anymore:
-- smallest factor of n, starting from d. directly jump from sqrt n to n.
smf (d,n) = head $ [ (x, quot n x) | x <- takeWhile ((<=n).(^2)) [d..]
, rem n x == 0] ++ [(n,1)]
pfactors n = map fst . takeUntil ((==1).snd) . tail . iterate smf $ (2,n)
This expresses guarded (co)recursion through a higher-order function iterate, and is functionally equivalent to that code mentioned above. The following now runs smoothly, and we're even able to find a pair of twin primes as a bonus there:
Prelude Saga> map pfactors [n3..]
[[71,839,1471,6857],[2,2,2,3,3,1259,6628403],[5,120170295029],[2,13,37,227,27514
79],[3,7,7,11,163,2279657],[2,2,41,3663728507],[600851475149],[2,3,5,5,19,31,680
0809],[600851475151],[2,2,2,2,37553217197],[3,3,3,211,105468049],[2,7,11161,3845
351],[5,67,881,2035853],[2,2,3Interrupted.
Here is my solution for Euler Project #3. It takes only 1.22 sec on my Macbook Air.
First we should find all factors of the given number. But we know, that even numbers can't be prime numbers (except number 2). So, to solve Euler Project #3 we need not all, but only odd factors:
getOddFactors num = [ x | x <- [3,5..num], num `rem` x == 0 ]
But we can optimize this function. If we plan to find a factor of num greater than sqrt num, we should have another factor which is less than sqrt num - and these possible factors we have found already. Hence, we can limit our list of possible factors by sqrt num:
getOddFactors num = [ x | x <- [3, 5..(floor.sqrt.fromIntegral) num],
num `rem` x == 0 ]
Next we want to know which of our odd factors of num are prime numbers:
isPrime number = [ x | x <- [3..(floor.sqrt.fromIntegral) number],
number `rem` x == 0] == []
Next we can filter odd factors of num with the function isPrime to find all prime factors of num. But to use laziness of Haskell to optimize our solution, we apply function filter isPrime to the reversed list of odd factors of the num. As soon as our function finds the first value which is prime number, Haskell stops computations and returns solution:
largestPrimeFactor = head . filter isPrime . reverse . getOddDivisors
Hence, the solution is:
ghci> largestPrimeFactor 600851475143
6857
(1.22 secs, 110646064 bytes)
This is a spoiler to task #3 of Project Euler! Don't continue to read, if you want to solve it by yourself.
I am trying to learn Haskell by writing programs for Project Euler. At the moment I'm trying to solve task #3 which asks for the largest prime factor of the number 600851475143.
To do this, I create a list liste which contains all numbers, which are divisors of this number (up to its squareroot). My strategy is now, to count the divisors of these numbers, to decide, if they are prime.
number = 600851475143
-- sn = sqrt number
sn = 775146
liste = [x | x <- [1..sn], (mod number x == 0)]
-- liste = [1,71,839,1471,6857,59569,104441,486847]
primelist :: Int -> [Int]
primelist z = [y | y <- [1..z], mod z y == 0]
main = print [primelist x | x <- liste]
The result, which should appear here, should be a list containing 8 lists with the divisors of the elements of liste. Instead, the list
[[1],[1,3],[1,29],[1,3,29,87]]
is printed.
How is this behaviour to be explained?
The Problem is the type declaration primelist :: Int -> [Int]. It forces Haskell to use native integers, i.e. 32-Bit integers on a 32-Bit platform. However, if you leave it out, Haskell will infer the function type to be Integer -> [Integer]. Integers allow computations with arbitrary precision, but are a little bit slower than native types.
To quote from "What's the difference between Integer and Int" in the Haskell FAQ:
Operations on Int can be much faster than operations on Integer, but
overflow and underflow can cause weird bugs.
Now isn't that the truth.
I am not sure if this will help you, but I also am working through Project Euler to help teach myself Haskell, and I devised the following solution:
defacto :: Integer -> Integer -> Integer
defacto x p | x == p = 1
| x`mod`p==0 = defacto (x`div`p) p
| otherwise = x
gpf :: Integer -> Integer
gpf = \x -> prim (x,primes)
prim :: (Integer,[Integer]) -> Integer
prim (x,(p:ps)) | p > x = 1
| (defacto x p) == 1 = p
| otherwise = prim((defacto x p),ps)
n :: Integer
n = 600851475143
Here, defacto de-factors a prime out of a number, so defacto 2 12 returns 4 and defacto 5 14 returns 14. gpf is a function to find the greatest prime factor, though it requires a list of primes up to x to be in scope. The key component is prim, which either returns 1 if the number is smaller than the next prime, returns the first prime in its prime list if x is a perfect power of that prime (i.e. if all other primes smaller than p have been factored out of x), and otherwise performs a recursive call on the defactored x and the truncated prime list. This has the effect of continuously shrinking x while linearly traversing the prime list, so that we need not test any primes that cannot factor into x, and we don't need to keep retesting the same primes on the reduced value of x. Hope this helps you.
While learning for an exam, I've just found the following task in an exercise:
Write a function that gives the integer logarithm to base 2 (rounded up) while only using multiplication and addition.
I tried, immediately, but couldn't come to any solution. I thought that would be an easy task but I could only find a solution when using integer division (e.g. in Haskell):
log2 :: Int -> Int
log2 1 = 0
log2 2 = 1
log2 x = 1 + log2 (x `div` 2)
Is this task possible with multiplication only at all? Using multiplication on the left side (pattern) always results in compiler errors. And using it on the right side, how can I trace the solution back to lower numbers?
And using it on the right side, how can I trace the solution back to lower numbers?
Recursion. Since it's easier to compute the floor, we use the fact that
ceiling (log_2 n) == floor (log_2 (2*n-1))
as can easily be seen. Then to find the logarithm to the base b, we compute the logarithm to base b² and adjust:
log2 :: Int -> Int
log2 1 = 0
log2 2 = 1
log2 n
| n < 1 = error "Argument of logarithm must be positive"
| otherwise = fst $ doLog 2 1
where
m = 2*n-1
doLog base acc
| base*acc > m = (0, acc)
| otherwise = case doLog (base*base) acc of
(e, a) | base*a > m -> (2*e, a)
| otherwise -> (2*e+1,a*base)
A simpler algorithm that needs more steps would be to simply iterate, multiplying with 2 in each step, and count, until the argument value is reached or surpassed:
log2 :: Int -> Int
log2 n
| n < 1 = error "agument of logarithm must be positive"
| otherwise = go 0 1
where
go exponent prod
| prod < n = go (exponent + 1) (2*prod)
| otherwise = exponent
How about:
log2 n = length (takeWhile (<n) (iterate (*2) 1))
?
I assume you can use functions from the Prelude (like error, fst and the comparison operators). If that's not allowed on the exam, you could theoretically use the definitions of length, takeWhile and iterate and end up with something relatively close (in spirit, probably not in the letter!) to Daniel's answer.
Maybe you can use series expansion to approximate the log function. Especially Taylor’s ones.