generate list with guards and recursion - haskell

I am trying to generate a list of perfect squares between 2 values i and n using recursion and guards. I can achieve this with list comprehension (i is not taken as an argument):
isPerfectSquare :: Integral a => a -> Bool
isPerfectSquare n = sq * sq == n
where sq = floor(sqrt(fromIntegral n :: Double))
squares :: Int -> [Int]
squares x = [y | y <- [1..x], isPerfectSquare y]
But I'm having trouble using recursion and guards for this. I'm trying to implement this without using higher order functions or list comprehension. I would appreciate someone pointing me in the right direction.

The usual trick is to generalize the task: instead of producing the squares in 1..x, produce those in a..b. This means writing an auxiliary function that takes both a and b as arguments.
Here's some skeleton code, to be adapted as needed.
squares :: Int -> [Int]
squares x = squaresFromTo 1 x
squaresFromTo :: Int -> Int -> [Int]
squaresFromTo a b
| a > b = ... -- no squares here!
| good a = ... -- keep a
| otherwise = ... -- discard a
where
otherSquares = squaresFrom (a+1) b
Now the question becomes: "how can we compute the squares in a..b knowing the recursive result otherSquares of the squares in a+1..b ?"

Related

Sum of cubes of positive integers of list using recursion (Haskell)

I'm trying to make a short Haskell function to compute the sum of the cubes of all positive integers in a list using recursion.
f'' :: [Int] -> Int
f''[] = 0
f'' (x:xs) = (x^3 + f''(xs))
But I can't figure out how to ensure only positive values of x are accepted.
You can filter, with guards, so then the function will look like:
f'' :: [Int] -> Int
f'' [] = 0
f'' (x:xs)
| x > 0 = x^3 + f''(xs)
| otherwise = …
where you still need to fill in the … part.

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'

Split a tuple into n parts

I am trying to create a function that receives a range of doubles (Double, Double) and an n (Int), where I divide this interval into n equal parts. I know that if it was a list, I did a Split in the list, but being in tuples and getting Doubles, I'm not sure what to do.
Thank you for any help
This is similar to #mschmidt's answer, but I think a list comprehension is probably clearest:
intervals :: Int -> (Double,Double) -> [(Double,Double)]
intervals n (a,b) =
let n' = fromIntegral n
d = (b - a) / n'
in [(a + i*d, a + (i+1)*d) | i <- [0..n'-1]]
giving:
> intervals 4 (1,10)
[(1.0,3.25),(3.25,5.5),(5.5,7.75),(7.75,10.0)]
>
If the duplicate calculation of the endpoint offends you, you could write:
intervals' :: Int -> (Double,Double) -> [(Double,Double)]
intervals' n (a,b) =
let n' = fromIntegral n
d = (b - a) / n'
x = [a + i*d | i <- [0..n']]
in zip x (tail x)
Note that zip x (tail x) is a pretty standard way to get tuples of consecutive pairs of a list:
> let x = [1,2,3,4] in zip x (tail x)
[(1,2),(2,3),(3,4)]
>
A rough sketch, probably not the most elegant solution:
Take the two input doubles (I call them l and u) and compute the width of the input range/interval.
You want to compute n output ranges of equal width w. Compute this w by dividing the input width by n.
Build a list of length n containing the values l+0*w, l+1*w, l+2*w, ...
Build the list of output tuples by combining the first two items in the list into a tuple. Drop one element of the list. Continue until only one element remains.
Try to catch all possible errors

How to generate an infinite list in Haskell based on two inputs?

I need to generate an infinite list based on two inputs.
gen :: Int -> Int -> [Int]
gen x y
Every element needs to be (x*y) and x is incremented by y each iteration and the original x must be in the list too.
So
gen 2 4
would result in
[2,8,24,40,..]
All of my attempts end up going forever (I use the call "take 4 (gen 2 4)" by in ghci the way) so I'm not sure how to proceed. Infinite lists just give me a lot of trouble.
I'm trying to do this through do-notation and the list monad. Any help in the right direction would be much appreciated.
EDIT
This was my last attempt which didnt work.
I'm learning Haskell through my friend and he gave me this problem to learn do notation for the list monad.
gen :: Int -> Int -> [Int]
gen x y =
do
a <- [x..]
guard $ mod a (x*y) == 0
let x = x+y
return a
I think you could create a List comprehension.
ghci> [2]++[(4*i+2)*4|i<-[0..]]
You can use this in your function. You can change variable x instead of number "2" and your "y" instead of the number "4". Try it.
Finally, I have made a concatenation (++) between the List Comprehension and a list with [2] (the variable x).
gen :: Int -> Int -> [Int]
gen x y = x : l
where l = fmap (\m -> y * (2 + m * y)) [0..]
testing:
take 5 $ gen 2 4
[2,8,24,40,56]

Recursion With Tuples in Haskell

I want to define a simple function in Haskell:
nzp :: [Int] -> (Int,Int,Int)
that accepts a list of integers as input and returns a triple (a,b,c) where a is the amount of numbers in the list less than 0, b is the amount equal to 0 and c is the amount higher than zero. For example,
nzp [3,0,-2,0,4,5] = (1,2,3)
I have to define this function recursively and I can only traverse the list once. How can I do this? I can't seem to grasp the concept of recursively creating a tuple.
Most Regards
Here are some pointers:
To use recursion to build up a value, you need to pass the previous version of the value as an argument, so write
nzp_helper :: [Int] -> (Int,Int,Int) -> (Int, Int, Int)
Decide what the answer is when the list is empty
nzp_helper [] runningTotals = -- what's the answer if the list is empty?
Decide what the answer is when there's something in the list
nzp_helper (i:is) (negatives, positives, zeros) =
| i < 0 = -- write stuff here
| i == 0 = -- I hope you're getting the idea
Kick the whole thing off by defining nzp using nzp_helper.
nzp is = nzp_helper is -- one final argument - what?
Instead of thinking of trying to create a single tuple recursively, you should think about updating an existing tuple containing the counts based on given value. This function would look something like:
update :: (Int, Int, Int) -> Int -> (Int, Int, Int)
update (l,e,g) x | x < 0 = (l+1, e, g)
update (l,e,g) x | x == 0 = (l, e+1, g)
update (l,e,g) x | x > 0 = (l, e, g+1)
Then you can traverse the input list using foldl and accumulate the output tuple:
nzp :: [Int] -> (Int, Int, Int)
nzp = foldl update (0,0,0)
EDIT: As #leftroundabout points out in the comments, you should avoid using foldl since it can lead to space leaks - you can find an explanation in Real World Haskell. You can use the strict version of foldl, foldl' in Data.List
import Data.List
nzp = foldl' update (0,0,0)
I can't seem to grasp the concept of recursively creating a tuple.
I shouldn't think so – in fact, it's impossible! (At least not without GHC extension havoc.)
No, you need to create a tuple in one go. The important thing needed for your function: since you may only traverse the list once, you need to pull through the entire tuple at once as well. As this is apparently homework, I shall instead show how it works with a fold (that is in fact preferrable, but translates quite directly to recursion):
nzp = foldr switchIncr (0,0,0)
where switchIncr x (negatives, zeroes, positives)
| x<0 = (succ negatives, zeroes, positives)
| x==0 = (negatives, succ zeroes, positives)
| otherwise = (negatives, zeroes, succ positives)
New to Haskell too! Perhaps not proper but here is my solution which works.
Define an auxiliary function that accumulates the n,z, and p values
let f (x:xs, (n, z, p)) | x < 0 = f (xs, (n+1, z, p))
| x == 0 = f (xs, (n, z+1, p))
| otherwise = f (xs, (n, z, p+1))
f ([], (n, z, p)) = ([], (n, z, p))
and define nzp in terms of the auxiliary function
let nzp x = snd $ f (x,(0,0,0))
to verify
Prelude> nzp [-1,1,1,-1,0]
(2,1,2)
I am a little over a couple of months into Haskell. A helper/auxilliary function would make running this solution easier.
s3 [] (l,g,z) = (l,g,z)
s3 (x:xs) (l,g,z) = if x<0
then (s3 xs (l+1,g,z))
else if x>0
then (s3 xs (l,g+1,z))
else (s3 xs (l,g,z+1))
This is run with s3 [1,0,-2,3,4,-7,0,-8] (0,0,0) producing
(3,3,2).
Just about any primitive recursive function can be translated into a fold.

Resources