What is the result of this function? - haskell

This is the code I got on my test and I'm wondering what the output would be:
funkcija[] _ = 0
funkcija (glava:rep) broj
| glava > broj = funkcija rep broj
| glava <= broj = glava + (funkcija rep broj)
funkcija [4,2,1,5,7,6] 2*3
Do I compare the head/first number in the array with 6 (2*3) or 2 and then multiply the sum with 3?
Is the correct answer 18 or 9?

Function application takes precedence over operators, so this is interpreted as:
(funkcija [4,2,1,5,7,6] 2) * 3
Your funkcija is in essence a sum that first filters: it only will sum up values that are less than or equal to the second parameter (here 2), so for [4,2,1,5,7,6] this will sum up 2 + 1 which is 3 and then multiply with three to obtain 9.
The funkcija can be replaced with:
funkcija :: (Num a, Ord a) => [a] -> a -> a
funkcija xs t = sum (filter (<= t) xs)

Related

Linear recursive method for counting palindrome numbers between 2 integers in Haskell

I'm solving a practice problem in Haskell where I'm trying to count the palindrome numbers between 2 given integers. Single-digit numbers are palindromes. I've tried solving it with a helper function but I can't make it take the smaller number from the main function. Any help would be appreciated!
So far I typed this:
main :: IO()
main = do
print $ countPalindromes 5 13 == 5 -- 6 7 8 9 11
print $ countPalindromes 13 5 == 5 -- 6 7 8 9 11
rev :: Int -> Int
rev n = helper n 0
where
helper :: Int -> Int -> Int
helper 0 result = result
helper n result = helper (div n 10) (result * 10 + mod n 10)
isPalindrome :: Int -> Bool
isPalindrome x = rev x == x
countPalindromes :: Int -> Int -> Int
countPalindromes a b
| a > b = helper b a 0
| otherwise = helper a b 0
where
helper :: Int -> Int -> Int -> Int
helper a b count
| a <= b && isPalindrome (a - 1) = count + 1
| otherwise = helper (a - 1) b count
That's not your problem. The problem is that helper a b count only returns count + 1 if a is a palindrome, without ever checking if a + 1, a + 2, etc, are palindromes as well. When the first number is a palindrome, it returns 0 + 1 == 1 and done. (Your definition of helper is also counting the wrong way; it's decrementing a instead of incrementing as you need to do if you ever want a <= b to be false.)
helper needs to recurse whether or not a is a palindrome; the only difference is in the value of its third argument.
helper a b count | a > b = count -- base
| isPalindrome a = helper (a + 1) b (count + 1)
| otherwise = helper (a + 1) b count
Note that b never changes; it doesn't need to be an argument to helper. Instead, you can make a recursive call to countPalindromes to ensure a < b:
countPalindromes :: Int -> Int -> Int
countPalindromes a b
| a > b = countPalindromes b a
| otherwise = helper a 0
where
helper :: Int -> Int -> Int
helper a count
| a > b = count -- base case
| isPalindrom a = helper (a + 1) (count + 1)
| otherwise = helper (a + 1) count
Tail recursion also isn't terribly important in Haskell. You can write helper more naturally
helper a | a > b = 0
| isPalindrome a = 1 + helper (a + 1)
| otherwise = helper (a + 1)
Note, too, that the only difference between isPalindrome returning True or False is whether you add 1 or 0 to the recursive return value. You can capture that with fromEnum:
helper a | a > b = 0
| otherwise = (fromEnum (isPalindrome a)) + helper (a + 1)
As an exercise, note that you don't need explicit recursion at all. You can use filter to get the values in range that are palindromes, then simply count the number of values in the resulting list.

Haskell tail recursion for Fibonacci sequence

So I am working on an assignment where I have to find the nth fibonacci number, and I came across this idea shown below, however this returns a list, and I would just like to return the final number, so for example fibo 3 would give me [0,1,1,2,3,5,8,13], except I just want 13 to return, is there any way I could do that? This is my first time using Haskell and I am sort of learning functional programming as well for the first time, any help is appreciated. Thanks
fibo :: Integral x => x -> [x]
fibo n = fiboHelper [0,1] 0 1 n
fiboHelper :: Integral x => [x]->x->x->x->[x]
fiboHelper l x y 0 = l
fiboHelper l x y n = fiboHelper (l ++ [y+x] ++ [y+x+y]) (x+y) (y+x+y) (n-1)
Yes, you can keep track of the last 2 steps as you go down the recursive stack.
fibo :: Integral x => x -> x
fibo a
| a < 3 = 1
| otherwise = go 2 1 1 where
go a' b' c'
| a' == a = c'
| otherwise = go (a'+1) (c') (b'+c')
On a side note, a very interesting way I learned to create an infinite list of Fibonacci numbers in Haskell is as follows:
fibs = 1 : scanl (+) 1 fibs
combining this with take and last you can achieve whatever solution you are looking for.
take 5 fibs
-- produces [1,1,2,3,5]
last $ take 5 fibs
-- produces 5
You can work with a helper function that contains two variables: the first and second item, and each
fibo :: (Integral a, Integral b) => a -> b
fibo 0 = 0
fibo n = fiboHelper 0 1 (n-1)
fiboHelper :: (Integral a, Integral b) => a -> a -> b -> a
fiboHelper si si1 n
| n <= 0 = si1
| otherwise = fiboHelper si1 (si+si1) (n-1)
This then produces:
Prelude> fibo 7
13
As for the algorithm in your question, usually appending at the right side of a list is not a good idea, since it runs in linear time with the size of the left operand. This thus means that your algorithm runs in O(n2) time. You can implement this as:
fibo :: (Integral a, Integral b) => a -> [b]
fibo 0 = [0]
fibo n = 0 : fiboHelper 0 1 (n-1)
fiboHelper :: (Integral a, Integral b) => a -> a -> b -> [a]
fiboHelper si si1 n
| n < 0 = []
| otherwise = si1 : fiboHelper si1 (si+si1) (n-1)
this will produce:
Prelude> fibo 7
[0,1,1,2,3,5,8,13]
Instead of a list, you only need to keep track of the last two Fibonacci numbers, so that you can add them together for the next iteration. The recurrence relation you want can be defined using
-- replace a and b with (a+b) and a, respectively, forgetting b.
helper a b n == fiboHelper (a+b) a (n-1)
helper a b 1 == a
helper _ b 0 == b
(The second case isn't strictly necessary, but avoids an unnecessary addition.)
As n gets smaller, the desired value "accumulates" in the second parameter, with the value when n == 0 being the final result.
Note that you can get different series by providing different initial values for a and b. For example, fibo = helper 1 0, while the Lucas numbers are defined by lucas = helper 1 2:
lucas 5 = helper 1 2 5
== helper 3 1 4
== helper 4 3 3
== helper 7 4 2
== helper 11 7 1
( == helper 18 11 0)
== 11

fractional type is in Haskell

I want to use rational number type instead of factional type in Haskell (or float/double type in C)
I get below result:
8/(3-8/3)=23.999...
8/(3-8/3)/=24
I know Data.Ratio. However, it support (+) (-) (*) (/) operation on Data.Ratio:
1%3+3%3 == 4 % 3
8/(3-8%3) == 24 % 1
I had checked in Racket:
(= (/ 8 (- 3 (/ 8 3))) 24)
#t
What's correct way to ensure 8/(3-8/3) == 24 in Haskell?
Use an explicit type somewhere in the chain. It will force the entire calculation to be performed with the corrrect type.
import Data.Ratio
main = do
print $ 8/(3-8/3) == 24
print $ 8/(3-8/3) == (24 :: Rational)
Prints
False
True
Data.Ratio.numerator and Data.Ratio.denominator return numerator an denominator of the ratio in reduced form so it is safe to compare denominator to 1 to check if ratio is an integer.
import Data.Ratio
eq :: (Num a, Eq a) => Ratio a -> a -> Bool
eq r i = d == 1 && n == i
where
n = numerator r
d = denominator r
main = print $ (8/(3-8%3)) `eq` 24

SumFromTo , A Recursive Function

I am trying to do a recursive function that should give the sum of all integers between and including its two arguments. For example,
sumFromTo 5 8 is 5 + 6 + 7 + 8 = 26. If the first argument is greater than the
second, the function should return 0.
This is what I got currently but I am a beginner and I don't think I did it right
sumFromTo :: Int -> Int -> Int
sumFromTo x y
| x == 1 = 1
| y == 1 = 1
| x > 1 && y > 1 = x + y sumFromTo (x - 1)
| otherwise = 0
Any help please?
You can use a list comprehension to do this very simply:
sumFromTo :: Int -> Int -> Int
sumFromTo x y = sum [x..y]
However, I'm not sure what you'd want to do if x == y.
In the code you've given, your recursive definition isn't correct syntax. You've only given sumFromTo one argument, when it needs two, and you appear to have missed a + between the y and the function.
λ> sumFromTo 8 5
0
λ> sumFromTo 5 8
26
λ> sumFromTo 8 8
8
λ>
[a..b] means a list with a step of 1 between a and b, so [1..4] is [1,2,3,4]
Thanks to Phylogenesis, here is a recursive definition:
sumFromTo :: Int -> Int -> Int
sumFromTo x y
| x > y = 0
| x == y = x
| otherwise = x + sumFromTo (x + 1) y
I think you make the problem too complex if you want to implement this with recursion. Basically there are two cases:
one where the lower bound is greater than the upper bound, in which case the sum is zero; and
one where the lower bound is less than or equal to the upper bound.
The first case (1) can be expressed by writing:
sumFromTo x y | x > y = 0
In the second case, the result is the lower bound plus the sum of the lowerbound plus one to the upper bound, so:
| otherwise = x + sumFromTo (x+1) y
and putting these together:
sumFromTo :: (Num a, Ord a) => a -> a -> a
sumFromTo x y | x > y = 0
| otherwise = x + sumFromTo (x+1) y

Haskell reverse Integer with recursion

I want to reverse an Integer in Haskell with recursion. I have a small issue.
Here is the code :
reverseInt :: Integer -> Integer
reverseInt n
| n>0 = (mod n 10)*10 + reverseInt(div n 10)
| otherwise = 0
Example 345
I use as input 345 and I want to output 543
In my program it will do....
reverseInt 345
345>0
mod 345 10 -> 5
reverseInt 34
34
34>0
mod 34 10 -> 4
reverseInt 3
3>0
mod 3 10 -> 3
reverseInt 0
0=0 (ends)
And at the end it returns the sum of them... 5+4+3 = 12.
So I want each time before it sums them, to multiple the sum * 10. So it will go...
5
5*10 + 4
54*10 + 3
543
Here's a relatively simple one:
reverseInt :: Int -> Int
reverseInt 0 = 0
reverseInt n = firstDigit + 10 * (reverseInt $ n - firstDigit * 10^place)
where
n' = fromIntegral n
place = (floor . logBase 10) n'
firstDigit = n `div` 10^place
Basically,
You take the logBase 10 of your input integer, to give you in what place it is (10s, 100s, 1000s...)
Because the previous calculation gives you a floating point number, of which we do not need the decimals, we use the floor function to truncate everything after the decimal.
We determine the first digit of the number by doing n 'div' 10^place. For example, if we had 543, we'd find place to be 2, so firstDigit = 543/100 = 5 (integer division)
We use this value, and add it to 10 * the reverse of the 'rest' of the integer, in this case, 43.
Edit: Perhaps an even more concise and understandable version might be:
reverseInt :: Int -> Int
reverseInt 0 = 0
reverseInt n = mod n 10 * 10^place + reverseInt (div n 10)
where
n' = fromIntegral n
place = (floor . logBase 10) n'
This time, instead of recursing through the first digit, we're recursing through the last one and using place to give it the right number of zeroes.
reverseInt :: Integer -> Integer
reverseInt n = snd $ rev n
where
rev x
| x>0 = let (a,b) = rev(div x 10)
in ((a*10), (mod x 10)*a + b)
| otherwise = (1,0)
Explanation left to reader :)
I don't know convenient way to found how many times you should multiply (mod n 10) on 10 in your 3rd line. I like solution with unfoldr more:
import Data.List
listify = unfoldr (\ x -> case x of
_ | x <= 0 -> Nothing
_ -> Just(mod x 10, div x 10) )
reverse_n n = foldl (\ acc x -> acc*10+x) 0 (listify n)
In listify function we generate list of numbers from integer in reverse order and after that we build result simple folding a list.
Or just convert it to a string, reverse it and convert it back to an integer:
reverseInt :: Integer -> Integer
reverseInt = read . reverse . show
More (not necessarily recursion based) answers for great good!
reverseInt 0 = 0
reverseInt x = foldl (\x y -> 10*x + y) 0 $ numToList x
where
numToList x = if x == 0 then [] else (x `rem` 10) : numToList (x `div` 10)
This is basically the concatenation of two functions : numToList (convert a given integer to a list 123 -> [1,2,3]) and listToNum (do the opposite).
The numToList function works by repeatedly getting the lowest unit of the number (using rem, Haskell's remainder function), and then chops it off (using div, Haskell's integer division function). Once the number is 0, the empty list is returned and the result concatenates into the final list. Keep in mind that this list is in reverse order!
The listToNum function (not seen) is quite a sexy piece of code:
foldl (\x y -> 10*x + y) 0 xs
This starts from the left and moves to the right, multiplying the current value at each step by 10 and then adding the next number to it.
I know the answer has already been given, but it's always nice to see alternative solutions :)
The first function is recursive to convert the integer to a list. It was originally reversing but the re-conversion function reversed easier so I took it out of the first. The functions can be run separately. The first outputs a tuple pair. The second takes a tuple pair. The second is not recursive nor did it need to be.
di 0 ls = (ls,sum ls); di n ls = di nn $ d:ls where (nn,d) = divMod n 10
di 3456789 []
([3,4,5,6,7,8,9],42)
rec (ls,n) = (sum [y*(10^x)|(x,y) <- zip [0..] ls ],n)
Run both as
rec $ di 3456789 []
(9876543,42)

Resources