Finding result of a recursive function - haskell

The given question is: "What is the value of f 572 for the following definition of f?"
f :: Int -> Int
f n = g n (n+1)
g :: Int -> Int -> Int
g m i
| (mod i m) == 0 = i
| otherwise = g m (i+1)
To me this looks like a recursive function and the answer should be that the values keep adding up from 572 till 1044 (that's when mod 1044 572 will be 0).

It is a very inefficient way to calculate the double (2*) of a number. Because you feed g n (n+1).
g is given two numbers and as long as (mod i m) == 0 fails (i is not dividable by m) it will increment i. From the moment it succeeds, it returns i. Now the lowest n larger than k that is dividable by k is obviously 2*k.
So f is equivalent to:
-- equivalent to
f' = (2*)
In case negative numbers are also considered, it will always return 0, for the strictly negative numbers since the first such number to satisfy the modulo relation is 0. Finally if 0 is given, it will error. So when considering zero and negative numbers, the full definition is:
-- equivalent (with negative numbers and zero)
f' n | n > 0 = 2*n
| n < 0 = 0
-- n == 0 should error
Since the algorithm increments i each time, the program will run linear with n (given increment and modulo can be checked in constant time) so O(n). The equivalent definition runs of course in constant time (given multiplication and comparisons can be done in constant time, this is not the case for Integer for instance).

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'

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

Haskell function that accepts function or value, then calls function or returns value

How can I write a type declaration and function in Haskell that takes either a function (that itself takes no arguments) or a value. When given a function it calls the function. When given a value it returns the value.
[edit] To give more context, I'm mostly curious how to solve this problem in Haskell without bit twiddling: Designing function f(f(n)) == -n
Sean
I'm mostly curious how to solve this problem in Haskell without bit twiddling: Designing function f(f(n)) == -n
That's actually quite easy to solve:
when :: (a -> Bool) -> (a -> a) -> a -> a
when p f x = if p x then f x else x
f :: Integer -> Integer
f = (+) <$> when even negate <*> signum
How do we derive this? Consider:
f (f n) = (-n) -- (0) - from the interview question
f x = y -- (1) - assumption
f y = (-x) -- (2) - from (0) and (1), f (f x) = (-x)
f (-x) = (-y) -- (3) - from (0) and (2), f (f y) = (-y)
f (-y) = x -- (4) - from (0) and (3), f (f (-x)) = x
Now, if you see the left hand sides of these equations then you'll notice that there are four cases:
f x.
f y.
f (-x).
f (-y).
Notice that the domain of the function f is divided into positive and negative numbers, x and (-x), and y and (-y). Let's assume that x and y together form the set of positive numbers and (-x) and (-y) together form the set of negative numbers.
The set of positive numbers is divided into two proper disjoint subsets, x and y. How do we divide the set of positive numbers into two proper disjoint subsets? Odd and even numbers are a good candidate. Hence, let's assume that x is the set of positive odd numbers and y is the set of positive even numbers.
Another advantage of using odd and even numbers is that when negated odd numbers remain odd and even numbers remain even. Hence, (-x) is the set of negative odd numbers and (-y) is the set of negative even numbers.
Now, consider the four cases again. Notice that the sign only changes when the number is even:
f x = y (sign does not change).
f y = (-x) (sign changes).
f (-x) = (-y) (sign does not change).
f (-y) = x (sign changes).
Hence, we only negate the number when it is even (i.e. when even negate).
Next, we need to convert odd numbers into even numbers and vice versa. The easiest way to do so is to add or subtract one from the number. However, care should be taken that the resulting number is not 0. Consider the special case of 0:
f 0 = z -- (a) - assumption
f z = (-0) -- (b) - from (0) and (a), f (f 0) = (-0)
f (-0) = (-z) -- (c) - from (0) and (b), f (f z) = (-z)
(-0) = 0 -- (d) - reflexivity
f (-0) = f 0 -- (e) - from (d)
(-z) = z -- (f) - from (a) and (c) and (e)
z = 0 -- (g) - from (d) and (f)
f 0 = 0 -- (h) - from (a) and (g)
Hence, f n = 0 if and only if n = 0. So let's consider the neighbors of 0, 1 and (-1). Both of them are odd numbers. Hence, they are not negated. However, they do need to be converted into an even number (except for 0). Hence, 1 is converted into 2 and (-1) is converted into (-2).
Thus, for odd numbers we simply add the sign of the number to the number itself.
Now, consider even numbers. We know:
f 1 = 2 -- (A)
f (-1) = (-2) -- (B)
Therefore:
f 2 = (-1) -- (C), from (0) and (A), f (f 1) = (-1)
f (-2) = 1 -- (D), from (0) and (B), f (f (-1)) = 1
We know that even numbers are always negated. Hence, 2 first becomes (-2) and vice versa. Let the original even number be n. Hence, first we negate n and then add signum n to it:
evenF n = negate n + signum n
evenF 2 = negate 2 + signum 2
= (-2) + 1
= (-1)
evenF (-2) = negate (-2) + signum (-2)
= 2 + (-1)
= 1
evenF 0 = negate 0 + signum 0
= 0 + 0
= 0
Thus, for both the odd case and the even case we add the sign of the original number to when even negate. Therefore, f is defined as:
f :: Integer -> Integer
f = (+) <$> when even negate <*> signum
Hope that helps.
You can't write a function with two different signatures (unless you use typeclasses, but typeclasses are not suitable for this problem). You must solve this in a way that lets you treat both functions and non-function values as the same type. There are two obvious options:
Use a sum type.
f :: Either (Int -> Char) Char -> Char
f (Left g) = g 1
f (Right c) = c
Use const to convert your non-function value into a function that ignores its argument:
f = ($ 42)
f chr --> '*'
f (const 'a') --> 'a'
However, since this is a very unHaskelly thing to ask for, I suspect that this is an XY problem.
You could do it like this:
data FunctionOrValue a
= Function (() -> a)
| Value a
getValue :: FunctionOrValue a -> a
getValue (Function f) = f ()
getValue (Value x) = x
However this is a bit silly.
It sounds like you're trying to defer values manually, but since Haskell is lazy, there's not normally a need to do this.
An answer based on the interview question you posted:
f n = if (abs fracN) > 1 then 1/fracN else - (1/fracN)
where
fracN = realToFrac n
The question specified that the input is an int; it did not specify that the result must also be an int.
Edit: if you must return an Int, note that the question allows you to specify a range of possible inputs. I use a limit of 1073741823 (half of the max value of a signed 32-bit int), which allows me to write this:
fint :: Int -> Int
fint 0 = 0
fint n = if (abs n) <= rangeVal then n+addend else -(n-addend)
where
rangeVal = 1073741823
negator = if n < 0 then -1 else 1
addend = negator*rangeVal
One of the nice thing in Haskell (IMHO) is there is no difference between a value and a function without parameter returning a value (thanks to lazyness AND purity). Or if you prefer, every value is in fact a function without parameter which will be evaluated when needed. Therefore there is no need to worry about that type of problem. There is no such thing like f(), it's just f.
For example, you can write
x = 3 :: Int
f = head [] :: Int -- should blow up but doesn't
head [x, f] -- note that f and x have the same type
> 3 -- doesn't blow up on f, because f is not called
head [f] -- blows up, when trying to print f

How can I produce a fixed length of numbers that sum up a given number in Haskell

I'm new to haskell world and wanted to know, given any positive integer and number of digits between 1-9 how can I find the combination of numbers that sum into the positive integer using the provided number of digits in Haskell. For example,
4 using two digits can be represented as a list of [[2,2],[3,1]] using three digits as a list of [[1,1,2]],
5 using two digits can be represented as a list of [[2,3],[4,1]] using three digits as a list of [[1,1,3],[2,2,1]]
Assuming that you want to avoid a brute-force approach, this can be regarded as a typical dynamic-programming problem:
import Data.Array
partitions :: Int -> Int -> [[Int]]
partitions m n = table ! (m, n, 9)
where
table = listArray ((1, 1, 1), (m, n, 9)) l
l = [f i j k | i <- [1 .. m], j <- [1 .. n], k <- [1 .. 9]]
f i 1 k = if i > k `min` 9 then [] else [[i]]
f i j k = [d : ds | d <- [1 .. k `min` pred i], ds <- table ! (i - d, j - 1, d)]
The idea is to construct a three-dimensional lazy array table in which a cell with index (i, j, k) contains all partitions ds of the positive integer i into lists of j digits drawn from [1 .. k] such that sum ds == i.
For example:
> partitions 4 2
[[2,2],[3,1]]
> partitions 4 3
[[2,1,1]]
> partitions 5 2
[[3,2],[4,1]]
> partitions 5 3
[[2,2,1],[3,1,1]]
If you really don't want to think about the problem, and you really should because dynamic programming is good brain food, then you can ask the computer to be smart on your behalf. For example, you could use a tool called an SMT solver to which the sbv package gives you easy access.
Encoding Partitioning in SBV
A great advantage of solvers is you merely need to express the problem and not the solution. In this case lets declare some number of integers (identified by len) which are values 1..9 that sum to a known result (sumVal):
intPartitions :: Int -> Int -> IO AllSatResult
intPartitions sumVal len = allSat $ do
xs <- mapM exists [show i | i <- [1..len]] :: Symbolic [SWord32]
mapM (constrain . (.< 10)) xs
mapM (constrain . (.> 0)) xs
return $ sum xs .== fromIntegral sumVal
Calling this function is rather simple we just have to import the right libraries and print out what are called the satisfying "models" for our problem:
import Data.SBV
import Data.List (nub,sort)
main = do
res <- intPartitions 5 3
print (nub (map sort (extractModels res :: [[Word32]])))
Notice I sorted and eliminated duplicate solutions because you didn't seem to care that [1,1,3], [3,1,1] etc were all solutions - you just want one permutation of the resulting assignments.
For these hard-coded values we have a result of:
[[1,1,3],[1,2,2]]
Well a simple brute force does the trick:
import Data.List
import Control.Monad
sums :: Int -> Int -> [[Int]]
sums number count = nub . map sort . filter ((==number) . sum) $ replicateM count [1..number+1-count]
Note that this is very inefficient. The usage of nub . map sort only shortens the result by removing doubled elements.
This is usually solved by using dynamic programming to avoid recomputing common sub-problems. But this is not the most important problem here: you need to start by coming up with the recursive algorithm! You will have plenty of time to think about producing an efficient solution once you've solved that problem. Hence this answer in two steps. The whole gist without comments is available here.
I start off by giving names to types because I'd get confused with all the Ints floating around and I consider types to be documentation. You might be more clever than I am and not need all this extra stuff.
type Target = Int
type Digits = Int
type MaxInt = Int
Now, the bruteforce solution: We're given the number of Digits left to partition a number, the Target number and the MaxInt we may use in this partition.
partitionMaxBrute :: Digits -> Target -> MaxInt -> [[Int]]
partitionMaxBrute d t m
If we have no digits left and the target is zero, we're happy!
| d == 0 && t == 0 = [[]]
If the product of Digits by MaxInt is smaller than Target or if the MaxInt itself is smaller than zero, there is no way we may succeed accumulating Digits non-zero numbers! :(
| d * m < t || m <= 0 = []
If MaxInt is bigger than our Target then we better decrease MaxInt if we want to have a solution. It does not make sense to decrease it to anything bigger than Target + 1 - Digits.
| t < m = partitionMaxBrute d t (t + 1 - d)
Finally, we may either lower MaxInt (we are not using that number) or substract MaxInt from Target and keep going (we are using MaxInt at least once):
| otherwise = partitionMaxBrute d t (m - 1)
++ fmap (m :) (partitionMaxBrute (d - 1) (t - m) m)
Given that solution, we can get our brute force partition: it's the one where the MaxInt we start with is Target + 1 - Digits which makes sense given that we are expecting a list of Digits non-zero numbers.
partitionBrute :: Digits -> Target -> [[Int]]
partitionBrute d t = partitionMaxBrute d t (t + 1 - d)
Now comes the time of memoization: dynamic programming is taking advantage of the fact that the smaller problems we solve are discovered through a lot of different paths and we do not need to recompute the answer over and over again. Easy caching is made possible by the memoize package. We simply write the same function with its recursive calls abstracted:
partitionMax :: (Digits -> Target -> MaxInt -> [[Int]]) ->
Digits -> Target -> MaxInt -> [[Int]]
partitionMax rec d t m
| d == 0 && t == 0 = [[]]
| d * m < t || m <= 0 = []
| t < m = rec d t (t + 1 - d)
| otherwise = rec d t (m - 1)
++ fmap (m :) (rec (d - 1) (t - m) m)
And make sure that we cache the values:
partition :: Digits -> Target -> [[Int]]
partition d t = memoPM d t (t + 1 - d)
where memoPM = memoize3 $ partitionMax memoPM
You can produce all partitions directly:
type Count = Int
type Max = Int
type Target = Int
partitions :: Count -> Max -> Target -> [[Int]]
partitions 0 m 0 = [[]]
partitions k m n = do
let m' = min m (n - k + 1)
d <- takeWhile (\d -> n <= k * d) [m', m' - 1 .. 1]
map (d:) $ partitions (k - 1) d (n - d)
It's easy to check, that there are no redundant cases. We just need to replace do with redundant $ do, where redundant is
redundant [] = [[]]
redundant xs = xs
If partitions (k - 1) d (n - d) returned [], then redundant would make [[]] from it, and then map (d:) $ partitions (k - 1) d (n - d) would be equal to [d]. But output doesn't change with the redundant function, so all partitions are generated directly.
The code is pretty simple and fast, since you want to produce partitions, rather than count them.

Logarithm in functional language with addition and multiplication only

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.

Resources