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
Related
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.
I want to create a function as mentioned in the title. The specific is that it adds the digits in reversed order, you can see that in the test cases: 12 -> 1; 852369 -> 628; 1714 -> 11; 12345 -> 42; 891 -> 9; 448575 -> 784; 4214 -> 14
The main idea is that when the number is bigger than 99 it enters the helper function which has i - indicator if the the digit is on an even position, and res which stores the result. Helper begins to cycle n as it checks whether or not the current digit is on even position and adds it to the result.
So far I've tried the following code:
everyOther :: Int -> Int
everyOther n
| n < 10 = error "n must be bigger than 10 or equal"
| n < 100 = div n 10
| otherwise = helper n 0 0
where
helper :: Int -> Int -> Int -> Int
helper n i res
| n < 100 = res
| i == 1 = helper (div n 10) (i - 1) (res + (mod n 10)*10)
| otherwise = helper (div n 10) i res
Any help would be appreciated!
You can obtain the one but last digit of x with mod (div x 10) 10. You can use this with an accumulator that accumulates the value by each time multiplying with 10, so:
everyOther :: Int -> Int
everyOther = go 0
where go a v
| v < 10 = a
| otherwise = go (10*a + mod (div v 10) 10) (div v 100)
If v is thus less than 10, we can return the accumulator, since there is no "other digit" anymore. If that is not the case, we multiply a with 10, and add mod (div v 10) 10 to add the other digit to it, and recurse with the value divided by 100 to move it two places to the right.
We can improve this, as #Daniel Wagner says, by making use of quotRem :: Integral a => a -> a -> (a, a):
everyOther :: Int -> Int
everyOther = go 0
where go a v
| v < 10 = a
| otherwise = let (q, r) = v `quotRem` 100 in go (10*a + r `quot` 10) q
here we thus work with the remainder of a division by 100, and this thus avoids an extra modulo.
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
I need to determine a recursive function crosssum :: Int -> Int in Haskell to calculate the cross sum of positive numbers. I am not allowed to use any functions from the hierarchical library besides (:), (>), (++), (<), (>=), (<=), div, mod, not (&&), max, min, etc.
crosssum :: Int -> Int
cross sum x = if x > 0
then x `mod` 10
+ x `div` 10 + crosssum x
else 0
so whenever I fill in e.g. crosssum 12 it says 'thread killed'. I do not understand how to get this right. I would appreciate any ideas. Thx
One of the problems with your code is that x is not reduced (or changed somehow) when it's passed as an argument to the recursive call of crosssum. That's why your program never stops.
The modified code:
crosssum :: Int -> Int
crosssum x = if x > 0
then x `mod` 10 + crosssum (x `div` 10)
else 0
is going to have the following logic
crosssum 12 = 2 + (crosssum 1) = 2 + (1 + (crosssum 0)) = 2 + 1 + 0
By the way, Haskell will help you to avoid if condition by using pattern-matching to receive more readable code:
crosssum :: Int -> Int
crosssum 0 = 0
crosssum x =
(mod x 10) + (crosssum (div x 10))
divMod in Prelude is very handy, too. It's one operation for both div and mod, In fact for all 2 digit numbers dm n = sum.sequence [fst,snd] $ divMod n 10
cs 0 = 0; cs n = m+ cs d where (d,m) = divMod n 10
cs will do any size number.
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)