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
Related
I am writing some code to work with arbitrary radix numbers in haskell. They will be stored as lists of integers representing the digits.
I almost managed to get it working, but I have run into the problem of converting a list of tuples [(a_1,b_1),...,(a_n,b_n)] into a single list which is defined as follows:
for all i, L(a_i) = b_i.
if there is no i such that a_i = k, a(k)=0
In other words, this is a list of (position,value) pairs for values in an array. If a position does not have a corresponding value, it should be set to zero.
I have read this (https://wiki.haskell.org/How_to_work_on_lists) but I don't think any of these methods are suitable for this task.
baseN :: Integer -> Integer -> [Integer]
baseN n b = convert_digits (baseN_digits n b)
chunk :: (Integer, Integer) -> [Integer]
chunk (e,m) = m : (take (fromIntegral e) (repeat 0))
-- This is broken because the exponents don't count for each other's zeroes
convert_digits :: [(Integer,Integer)] -> [Integer]
convert_digits ((e,m):rest) = m : (take (fromIntegral (e)) (repeat 0))
convert_digits [] = []
-- Converts n to base b array form, where a tuple represents (exponent,digit).
-- This works, except it ignores digits which are zero. thus, I converted it to return (exponent, digit) pairs.
baseN_digits :: Integer -> Integer -> [(Integer,Integer)]
baseN_digits n b | n <= 0 = [] -- we're done.
| b <= 0 = [] -- garbage input.
| True = (e,m) : (baseN_digits (n-((b^e)*m)) b)
where e = (greedy n b 0) -- Exponent of highest digit
m = (get_coef n b e 1) -- the highest digit
-- Returns the exponent of the highest digit.
greedy :: Integer -> Integer -> Integer -> Integer
greedy n b e | n-(b^e) < 0 = (e-1) -- We have overshot so decrement.
| n-(b^e) == 0 = e -- We nailed it. No need to decrement.
| n-(b^e) > 0 = (greedy n b (e+1)) -- Not there yet.
-- Finds the multiplicity of the highest digit
get_coef :: Integer -> Integer -> Integer -> Integer -> Integer
get_coef n b e m | n - ((b^e)*m) < 0 = (m-1) -- We overshot so decrement.
| n - ((b^e)*m) == 0 = m -- Nailed it, no need to decrement.
| n - ((b^e)*m) > 0 = get_coef n b e (m+1) -- Not there yet.
You can call "baseN_digits n base" and it will give you the corresponding array of tuples which needs to be converted to the correct output
Here's something I threw together.
f = snd . foldr (\(e,n) (i,l') -> ( e , (n : replicate (e-i-1) 0) ++ l')) (-1,[])
f . map (fromIntegral *** fromIntegral) $ baseN_digits 50301020 10 = [5,0,3,0,1,0,2,0]
I think I understood your requirements (?)
EDIT:
Perhaps more naturally,
f xs = foldr (\(e,n) fl' i -> (replicate (i-e) 0) ++ (n : fl' (e-1))) (\i -> replicate (i+1) 0) xs 0
I am trying to build a function that converts a Decimal(Int) into a Binary number.
Unfortunately other than in java it is not possible to divide an int by two in haskell.
I am very new to functional programming so the problem could be something trivial.
So far I could not find another solution to this problem but
here is my first try :
fromDecimal :: Int -> [Int]
fromDecimal 0 = [0]
fromDecimal n = if (mod n 2 == 0) then
do
0:fromDecimal(n/2)
else
do
1:fromDecimal(n/2)
I got an java implementation here which I did before :
public void fromDecimal(int decimal){
for (int i=0;i<values.length;i++){
if(decimal % 2 = 0)
values[i]=true ;
decimal = decimal/ 2;
else {values[i]= false;
} }
}
Hopefully this is going to help to find a solution!
There are some problems with your solution. First of all, I advise not to use do at all, until you understand what do does. Here we do not need do at all.
Unfortunately other than in java it is not possible to divide an int by two in haskell.
It actually is, but the / operator (which is in fact the (/) function), has type (/) :: Fractional a => a -> a -> a. An Int is not Fractional. You can perform integer division with div :: Integral a => a -> a -> a.
So then the code looks like:
fromDecimal :: Int -> [Int]
fromDecimal 0 = [0]
fromDecimal n = if (mod n 2 == 0) then 0:fromDecimal (div n 2) else 1:fromDecimal (div n 2)
But we can definitely make this more elegant. mod n 2 can only result in two outcomes: 0 and 1, and these are exactly the ones that we use at the left side of the (:) operator.
So we do not need to use an if-then-else at all:
fromDecimal :: Int -> [Int]
fromDecimal 0 = [0]
fromDecimal n = mod n 2 : fromDecimal (div n 2)
Likely this is still not exactly what you want: here we write the binary value such that the last element, is the most significant one. This function will add a tailing zero, which does not make a semantical difference (due to that order), but it is not elegant either.
We can define an function go that omits this zero, if the given value is not zero, like:
fromDecimal :: Int -> [Int]
fromDecimal 0 = [0]
fromDecimal n = go n
where go 0 = []
go k = mod k 2 : go (div k 2)
If we however want to write the most significant bit first (so in the same order as we write decimal numbers), then we have to reverse the outcome. We can do this by making use of an accumulator:
fromDecimal :: Int -> [Int]
fromDecimal 0 = [0]
fromDecimal n = go n []
where go 0 r = r
go k rs = go (div k 2) (mod k 2:rs)
You cannot / integers in Haskell – division is not defined in terms of integral numbers! For integral division use div function, but in your case more suitable would be divMod that comes with mod gratis.
Also, you are going to get reversed output, so you can reverse manually it after that, or use more memory-efficient version with accumulator:
decToBin :: Int -> [Int]
decToBin = go [] where
go acc 0 = acc
go acc n = let (d, m) = n `divMod` 2 in go (m : acc) d
go will give you an empty list for 0. You may add it manually if the list is empty:
decToBin = (\l -> if null l then [0] else l) . go [] where ...
Think through how your algorithm will work. It starts from 2⁰, so it will generate bits backward from how we ordinarily think of them, i.e., least-significant bit first. Your algorithm can represent non-negative binary integers only.
fromDecimal :: Int -> [Int]
fromDecimal d | d < 0 = error "Must be non-negative"
| d == 0 = [0]
| otherwise = reverse (go d)
where go 0 = []
go d = d `rem` 2 : go (d `div` 2)
In Haskell, when we generate a list in reverse, go ahead and do so but then reverse the result at the end. The reason for this is consing up a list (gluing new items at the head with :) has a constant cost and the reverse at the end has a linear cost — but appending with ++ has a quadratic cost.
Common Haskell style is to have a private inner loop named go that the outer function applies when it’s happy with its arguments. The base case is to terminate with the empty list when d reaches zero. Otherwise, we take the current remainder modulo 2 and then proceed with d halved and truncated.
Without the special case for zero, fromDecimal 0 would be the empty list rather than [0].
The binary numbers are usually strings and not really used in calculations.
Strings are also less complicated.
The pattern of binary numbers is like any other. It repeats but at a faster clip.
Only a small set is necessary to generate up to 256 (0-255) binary numbers.
The pattern can systematically be expanded for more.
The starting pattern is 4, 0-3
bd = ["00","01","10","11"]
The function to combine them into larger numbers is
d2b n = head.drop n $ [ d++e++f++g | d <- bd, e <- bd, f <- bd, g <- bd]
d2b 125
"01111101"
If it's not obvious how to expand, then
bd = ["000","001","010","011","100","101","110","111"]
Will give you up to 4096 binary digits (0-4095). All else stays the same.
If it's not obvious, the db2 function uses 4 pairs of binary numbers so 4 of the set. (2^8) - 1 or (2^12) - 1 is how many you get.
By the way, list comprehension are sugar coated do structures.
Generate the above patterns with
[ a++b | a <- ["0","1"], b <- ["0","1"] ]
["00","01","10","11"]
and
[ a++b++c | a <- ["0","1"], b <- ["0","1"], c <- ["0","1"] ]
["000","001","010","011","100","101","110","111"]
More generally, one pattern and one function may serve the purpose
b2 = ["0","1"]
b4 = [ a++b++c++d | a <- b2, b <- b2, c <- b2, d <- b2]
b4
["0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"]
bb n = head.drop n $ [ a++b++c++d | a <- b4, b <- b4, c <- b4, d <- b4]
bb 32768
"1000000000000000"
bb 65535
"1111111111111111"
To calculate binary from decimal directly in Haskell using subtraction
cvtd n (x:xs) | x>n = 0:(cvtd n xs)
| n>x = 1:(cvtd (n-x) xs)
| True = 1:[0|f<-xs]
Use any number of bits you want, for example 10 bits.
cvtd 639 [2^e|e<-[9,8..0]]
[1,0,0,1,1,1,1,1,1,1]
import Data.List
dec2bin x =
reverse $ binstr $ unfoldr ndiv x
where
binstr = map (\x -> "01" !! x)
exch (a,b) = (b,a)
ndiv n =
case n of
0 -> Nothing
_ -> Just $ exch $ divMod n 2
Learning Haskell. Trying to write a function called nextPrime n that will return the next prime number after n.
I have the following:
-- Generate a list of all factors of n
factors :: Integral a => a -> [a]
factors n = [x | x <- [1..n], n `mod` x == 0]
-- True iff n is prime
isPrime :: Integral a => a -> Bool
isPrime n = factors n == [1, n]
So far the function is set up like so:
nextPrime :: Integral a => a -> a
nextPrime n =
I presume I have to do a sort of while loop maybe but not sure how. I am totally new to functional programming. Any help is appreciated
I assumed that nextPrime n means "get me the first prime number that's greater than n".
Here's an idea:
nextPrime :: Integral a => a -> a
nextPrime n = nextPrime' (n + 1)
where nextPrime' m = ...
You want to fill in the blanks for nextPrime'. Here's a hint:
fun n = if n <= 0
then 0
else n + fun (n - 1)
This is a recursive function that calculates the sum 1 + 2 + 3 + ... + n, though it does it starting with n and going down from there. nextPrime' will have to go up.
Hello I want to take a sum of functions call in Haskel but I cannot figure out what I am doing wrong. To be more specific, I have a function f(a,b,c)=a+b+c and I want to take an int like this:
x=Sum( from i=0 to i=c) f(1,1,i)
so far I have written this, but it doesn't even compile. Can you help me?
f a b c = a+b+c
my_sum f a b c+1 =f a b c+1 + my_sum f a b c
I get parse error in pattern my_sum
eg for my_sum f 1 1 5 the result would be f(1,1,5)+f(1,1,4)+f(1,1,3)+f(1,1,2)+f(1,1,1)
I dont want to use lists
n+k patterns are bad
Your code:
my_sum f a b c+1 =f a b c+1 + my_sum f a b c
includes a pattern in the form c+1 which A) should have parentheses B) Needs a base case (I assume you want to stop when c == 0) and C) is a syntactic form that has been removed from the language.
Instead, explicitly subtract 1 from c when you want and be sure to handle the base case:
my_sum f a b 0 = f a b 0
my_sum f a b n = f a b n + my_sum f a b (n-1)
This also has a memory leak meaning it will build up a large computation in the form f1 + (f a b n' + (f a b n'' + (f a b n''' + (.... You can handle the leak by using an accumulator or a higher level function and optimization at compile-time.
A cleaner Solution
List comprehension strikes me as the most reasonable solution here:
sum [f a b i | i <- [0..c] ]
The sum of the function f applied to arugments a, b and finally i where i ranges from 0 to c inclusively.
You can't have the c+1 on the left side of a definition. Since you're just summing, it doesn't matter if you count up from 0 to c or count down from c to 0, so you could instead do
my_sum f a b 0 = f a b 0
my_sum f a b c = f a b c + my_sum f a b (c - 1)
Then you could use it as
> let g x y z = x + y + z
> my_sum g 0 0 10
55
Some more detail on why your code failed to compile: Whenever you have a pattern on the left side of a definition, such as
fib 0 = 1
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
You can only match on constructors, names (like n or c), and literals (which are essentially constructors for the basic types). The function + is not a constructor, it is a function belonging to the Num typeclass, so therefore you can not pattern match on it. You may be confused from seeing list pattern matching before because it uses an operator:
myListSum [] = 0
myListSum (x:xs) = x + myListSum xs
but in fact, : is the Cons constructor for lists, and [] is the empty list constructor. You can think of the list type defined as
data [a] = [] | a : [a]
Or, if you were to replace all the symbols with words
data List a = Empty | Cons a (List a)
although its a bit different in reality since there's more that goes into defining lists, but that's the basic idea. This means that a pattern like
f [] = ...
f (x:xs) = ...
Is equivalent to
f Empty = ...
f (Cons x xs) = ...
just with more convenient syntax.
However, Int can be though of as a very large ADT defined as
data Int = -2147483648 | -2147483647 | ... | -1 | 0 | 1 | ... | 2147483646 | 2147483647
where each number itself is a different constructor. Then you can match on any individual number, but not anything like (x + 1) or (x * 2), because + and * are not constructors, just regular functions. (Note: Int is not actually defined this way because that would be really inefficient, it's defined at a more primitive level)
You can get from list formulations to the non-list, recursive formulations, with manual inlining and fusing of the functions in play:
{-# LANGUAGE BangPatterns #-}
import Data.List
f a b c = a+b+c
g f a b c = sum . map (f a b) $ [0..c]
= foldl' (\ !x y -> x + f a b y) 0 $ enumFromTo 0 c
= h 0 0 where
h !acc i | i > c = acc
| otherwise = h (acc + f a b i) (i+1)
Strictness annotations prevent uncontrolled build-up of thunks and stack overflow for big values of c.
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)