ruby while loop translated to haskell - haskell

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.

Related

Prime Factorization in Haskell to return a list of tuples giving the number and the power

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'

Solving a problem recursively regarding access to certain elements of an infinite list

My problem itself is not important at all, but I will state it so you can understand what essentially I'm trying to understand.
Nicomano said that you can calculate the cube of a natural number m like this:
for m=1, take the first odd number, sum them, and that is the cube (1^3 = 1)
for m=2, take the two next odds numbers,sum them, and that is the cube (2^3 = 3 + 5)
for m=3, take the three next odds numbers, sum them, and that is the cube (3^3 = 7 + 9 + 11)
And so on.
Solving this is easy just like this
--first we create an infinite odd list
odds :: [Integer]
odds = [i | i<-[1..], not (even i)]
--now the function
nicomano :: Int -> Integer
nicomano m = sum (take m (drop (sum[1..(m-1)]) odds))
Problem is, if I want to solve this recursively. When I try to do this, I ask myself the relation (mathematically speaking) between one nicomano m iteration and the previous one nicomano m-1.
The relation I found is the following one:
nicomano m = take (sum [1..m]) odds - (nicomano(1)+nicomano(2)+...+nicomano(m-1))
But this won't work to find a recursive solution, as I need the previous values of nicomano function for calculating the nicomano(m) one, and Haskell doesn't allow saving values in a list like in Python for example. Also If I could do it, it wouldn't be a recursive solution.
So how could we do this? Isn't it a good approach for finding recursive solutions to ask yourself about the relationship between one step and another?
Your current function Int -> Integer is just f m = m ** 3, and there's no nice recurrence to exploit in the nicomano manner.
Instead, I would suggest you build a function to generate the list of odds for the respective step:
nicomano :: Int -> [Integer]
nicomano 0 = [1, 3..]
nicomano n = drop n $ nicomano $ n - 1
cube :: Int -> Integer
cube n = sum $ take n $ nicomano $ n - 1
You might also find a tail-recursive formulation of this, but I think that's more ugly.
Another approach, specially suited for lazy evaluation of Haskell, is building an infinite sequence:
cube :: Int -> Integer
cube = \n -> cubes !! n
where
cubes = nicomano 0 [1, 3..]
nicomano i odds = let (begin, rest) = splitAt i odds
in sum begin : nicomano (i+1) rest

How to tell if a number is a square number with recursion?

I solved the following exercise, but I'm not a fan of the solution:
Write the function isPerfectSquare using recursion, to tell if an
Int is a perfectSquare
isPerfectSquare 1 -> Should return True
isPerfectSquare 3 -> Should return False
the num+1 part is for the case for isPerfectSquare 0 and isPerfectSquare 1, one of the parts I don't like one bit, this is my solutiuon:
perfectSquare 0 1 = [0] ++ perfectSquare 1 3
perfectSquare current diff = [current] ++ perfectSquare (current + diff) (diff + 2)
isPerfectSquare num = any (==num) (take (num+1) (perfectSquare 0 1))
What is a more elegant solution to this problem? of course we can't use sqrt, nor floating point operations.
#luqui you mean like this?
pow n = n*n
perfectSquare pRoot pSquare | pow(pRoot) == pSquare = True
| pow(pRoot)>pSquare = perfectSquare (pRoot-1) pSquare
| otherwise = False
--
isPerfectSquare number = perfectSquare number number
I can't believe I didn't see it xD thanks a lot! I must be really tired
You can perform some sort of "binary search" on some implicit list of squares. There is however a problem of course, and that is that we first need an upper bound. We can use as upper bound the number itself, since for all integral squares, the square is larger than the value we square.
So it could look like:
isPerfectSquare n = search 0 n
where search i k | i > k = False
| j2 > n = search i (j-1)
| j2 < n = search (j+1) k
| otherwise = True
where j = div (i+k) 2
j2 = j * j
To verify that a number n is a perfect square, we thus have an algorithm that runs in O(log n) in case the integer operations are done in constant time (for example if the number of bits is fixed).
Wikipedia suggests using Newton's method. Here's how that would look. We'll start with some boilerplate. ensure is a little combinator I've used fairly frequently. It's written to be very general, but I've included a short comment that should be pretty explanatory for how we'll plan to use it.
import Control.Applicative
import Control.Monad
ensure :: Alternative f => (a -> Bool) -> a -> f a
ensure p x = x <$ guard (p x)
-- ensure p x | p x = Just x
-- | otherwise = Nothing
Here's the implementation of the formula given by Wikipedia for taking one step in Newton's method. x is our current guess about the square root, and n is the number we're taking the square root of.
stepApprox :: Integer -> Integer -> Integer
stepApprox x n = (x + n `div` x) `div` 2
Now we can recursively call this stepping function until we get the floor of the square root. Since we're using integer division, the right termination condition is to watch for the next step of the approximation to be equal or one greater to the current step. This is the only recursive function.
iterateStepApprox :: Integer -> Integer -> Integer
iterateStepApprox x n = case x' - x of
0 -> x
1 -> x
_ -> iterateStepApprox x' n
where x' = stepApprox x n
To wrap the whole development up in a nice API, to check if a number is a square we can just check that the floor of its square root squares to it. We also need to pick a starting approximation, but we don't have to be super smart -- Newton's method converges very quickly for square roots. We'll pick half the number (rounded up) as our approximation. To avoid division by zero and other nonsense, we'll make zero and negative numbers special cases.
isqrt :: Integer -> Maybe Integer
isqrt n | n < 0 = Nothing
isqrt 0 = Just 0
isqrt n = ensure (\x -> x*x == n) (iterateStepApprox ((n+1)`div`2) n)
Now we're done! It's pretty fast even for large numbers:
> :set +s
> isqrt (10^10000) == Just (10^5000)
True
(0.58 secs, 182,610,408 bytes)
Yours would spend rather a longer time than the universe has got left computing that. It is also marginally faster than the binary search algorithm in my tests. (Of course, not hand-rolling it yourself is several orders of magnitude faster still, probably in part because it uses a better, but more complicated, algorithm based on Karatsuba multiplication.)
If the function is recursive then it is primitive recursive as are 90% of all recursive functions. For these folds are fast and effective. Considering the programmers time, while keeping things simple and correct is important.
Now, that said, it might be fruitful to cinsider text patterns of functions like sqrt. sqrt return a floating point number. If a number is a perfect square then two characters are ".0" at the end. The pattern might occur, however, at the start of any mantissa. If a string goes in, in reverse, then "0." is at the top of the list.
This function takes a Number and returns a Bool
fps n = (take 2.reverse.show $ (n / (sqrt n))) == "0."
fps 10000.00001
False
fps 10000
True

Keep getting stack overflow

I am repeatedly getting a stack overflow on my solution to Project Euler #7 and i have no idea why.
Here is my code:
import System.Environment
checkPrime :: Int -> Bool
checkPrime n = not $ testList n [2..n `div` 2]
--testList :: Int -> [Int] -> Bool
testList _ [] = False
testList n xs
| (n `rem` (head xs) == 0) = True
| otherwise = testList n (tail xs)
primesTill n = sum [1 | x <- [2..n], checkPrime x]
nthPrime n = nthPrime' n 2
nthPrime' n x
| (primesTill x == n) = x
| otherwise = nthPrime' n x+1
main = print (nthPrime 10001)
resolving the stackoverflow
As #bheklilr mentioned in his comment the stackoverflow is caused by a wrong evaluation order in the otherwise branch of the nthPrime' function:
nthPrime' n x+1
Will be interpreted as
(nthPrime' n x)+1
Because this expression is called recursively, your call of nthPrime' n 2 will expand into
(nthPrime' n 2)+1+1+1+1+1+1+1+1 ...
but the second parameter will never get incremented and your program collects a mass of unevaluated thunks. The evaluation can only happen if the first parameter is reduced to an Int, but your function is in an endless recursion so this will never take place. All the plus ones are stored on the stack, if there is no more space left you'll get a stackoverflow error.
To solve this problem you need to put parranteses around the x+1 so your recursive call will look like this
nthPrime' n (x+1)
Now the parameters gets incremented before it is passed to the recursive call.
This should solve your stackoverflow problem, you can try it out with a smaller number e.g. 101 and you'll get the desired result.
runtime optimization
If you test your program with the original value 10001 you may realize that it still won't finish in a reasonable amount of time.
I won't go into the details of fancy algorithms to solve this problems, if you're interested in them you can easily find them online.
Instead I'll show you were the problem in your code is and show you a simple solution.
The bottleneck is your nthPrime function:
primesTill n = sum [1 | x <- [2..n], checkPrime x]
nthPrime n = nthPrime' n 2
nthPrime' n x
| (primesTill x == n) = x
| otherwise = nthPrime' n (x+1)
This function checks if the number of primes between 2 and x is equal to n. The idea is correct, but it leads to an exponential runtime. The problem is that you recalculate primesTill x for every iteration. To count the primes smaller than x you calculate them all and than sum them up. In the next step for x+1 you forget every thing you know about the numbers between 2 and x and test them all again if they are prime only as a last step you test the if x+1 is prime. Than you repeat this - forget every thing and test all numbers again - until you are finished.
Wouldn't it be great if the computer could remember the primes it has already found?
There are many possibilities to do this I'll use a simple infinite list, if you are interested in other approaches you can search for the terms memoization or dynamic programming.
We start with the list comprehension you used in primesTill:
[1 | x <- [2..n], checkPrime x]
This calculates all primes between 2 and n, but immediately forgets the prime number and replaces it with 1, so the first step will be to keep the actual numbers.
[x | x <- [2..n], checkPrime x]
This gives us a list of all prime numbers between 2 and n. If we had a sufficiently large list of prime numbers we could use the index function !! to get the 10001st prime number. So we need to set n to a really really big number, to be sure that the filtered list is long enough?
Lazy evaluation to the rescue!
Lazy evaluation in haskell allows us to build an infinite list, that is only evaluated as much as needed. If we don't supply an upper bound to a list generator it will build such an infinite list for us.
[x | x <- [2..], checkPrime x]
Now we have a infinite list of all prime numbers.
We can bind it to the a name e.g. primes and use it to define nthPrime
primes = [x | x <- [2..], checkPrime x]
nthPrime n = primes !! n
Now you can compile it with ghc -O2, run it and the result will be promptly delivered to you.

Iterating a function and analysing the result in haskell

Ok, referring back to my previous question, I am still working on learning haskell and solving the current problem of finding the longest chain from the following iteration:
chain n | n == 0 = error "What are you on about?"
| n == 1 = [1]
| rem n 2 == 0 = n : chain (n `div` 2)
| otherwise = n : chain (3 * n + 1)
I have this bit sorted, but I need to find the longest chain from a starting number below 1,000,000. So how do I make it do each starting number up to 1,000,000 and then print the one with the longest chain length.
I can do it for one example with:
Main> length (chain n)
I assume I need the output as an array and then use the maximum function to find the value largest chain length and then see how far along it is in the array of answers.
Is this a good way to go about finding a solution or is there a better way (perhaps with better efficiency)?
You are right about the maximum part. To get the list (that's what Haskell's []s are, arrays are different structures) you need to use the map higher-order function, like this:
chainLength n = length (chain n)
lengths = map chainLength [1..1000000]
Essentially, map takes as arguments a function and a list. It applies the function to each element in the list and returns the list of the results.
Since you will be needing the number whose chain has that length, you may want change the chainLength function to return the number as well, like this:
chainLength n = (n, length (chain n))
That way you will have an array of pairs, with each number and its chain length.
Now you need to get the pair with the largest second component. That's where the maximumBy function comes in. It works just like maximum but takes a function as a parameter to select how to compare the values. In this case, the second component of the pair. This comparison function takes two numbers and returns a value of type Ordering. This type has only three possible values: LT, EQ, GT, for less than, equal, and greater than, respectively.
So, we need a function that given two pairs tells us how the second components compare to each other:
compareSnd (_, y1) (_, y2) = compare y1 y2
-- Or, if you import Data.Function, you can write it like this (thanks alexey_r):
compareSnd = compare `on` snd -- reads nicely
I used the default compare function that compares numbers (well, not just numbers).
Now we only need to get the maximum using this function:
longestChain = maximumBy compareSnd lengths
That gets you a pair of the number with the longest chain and the corresponding length. Feel free to apply fst and snd as you please.
Note that this could be more much more concisely using zip and composition, but since you tagged the question as newbie, I thought it better to break it down like this.
SPOILER (solving the problem for positive integers under 100):
module Test where
import Data.List -- this contains maximumBy
chain n
| n == 0 = error "What are you on about?"
| n == 1 = [1]
| rem n 2 == 0 = n : chain (n `div` 2)
| otherwise = n : chain (3 * n + 1)
chains = map (\x -> (x,chain x)) [1..100]
cmpSnd (a,b) (c,d)
| length b > length d = GT
| length b == length d = EQ
| otherwise = LT
solve = (fst . maximumBy cmpSnd) chains
The chains function makes use of map. It applies a function to every element of a list of a values, so
map succ [1,2]
is the same as
[succ 1,succ 2]
The cmpSnd function is a comparison function that probably exists somewhere deep in the Hierarchical Libraries, but I could not find it, so I created it. GT means "the first value is greater than the second", the rest is trivial.
Solve takes the maximum (by utilizing the comparison function we defined earlier) of the list. This will be a pair of an integer and a list. It will return the integer only (because of the fst).
A comment: Your chain function is not tail-recursive. This means that large chains will inevitably result in a Stack Overflow. You shall add an explicit accumulator variable and make it tail-recursive.
Something like
fst $ maximumBy (length . snd) $ zip [1..1000000] $ map chain [1..1000000]
(untested)
i.e. don't work out how far along the longest chain is in the list of longest chains, but carry around the seed values with the chains instead.
I studied Haskell years ago, so I don't remember it that well. On the other hand I've tested this code and it works. You will get the max chain and the number that generates it. But as fiships has stated before, it will overflow for big values.
chain :: Int -> [Int]
chain n
| n == 0 = []
| n == 1 = [1]
| rem n 2 == 0 = n : chain (n `div` 2)
| otherwise = n : chain (3 * n + 1)
length_chain :: Int -> Int
length_chain n = length (chain n)
max_pos :: (Int,Int) -> Int -> [Int] -> (Int,Int)
max_pos (m,p) _ [] = (m,p)
max_pos (m,p) a (x:xs)
| x > m = max_pos (x,a) (a+1) xs
| otherwise = max_pos (m,p) (a+1) xs
The instruction will be
Main> max_pos (0,0) 1 (map length_chain [1..10000])
(262,6171)

Resources