I'm new to Haskell, and I like its graceful grammar. But I haven't found a suitable way to define an infinite 2D array -- for example, the Pascal Triangle:
1 1 1 1 1 ...
1 2 3 4 5 ...
1 3 6 10 15 ...
1 4 10 20 35 ...
1 5 15 35 70 ...
...
I know how to define a simple function:
pascal :: Int -> Int -> Int
pascal 1 _ = 1
pascal _ 1 = 1
pascal x y = (pascal (x - 1) y) + (pascal x (y - 1))
Since Haskell do not memorize function values, a call to pascal 20 20 will take a long time. How could I define a fast version (like an infinite 2D array)?
You can create the pascal triangle as an infinite, lazy, nested list
pascal :: [[Integer]]
pascal = repeat 1 : map (scanl1 (+)) pascal
The above definition is a bit terse but what it essentially means is just that each row is an accumulating sum of the previous row, starting from repeat 1 i.e. an infinite list of ones. This has the advantage that we can calculate each value in the triangle directly without doing any O(n) indexing.
Now you can index the list to find the value you need, e.g.
> pascal !! 19 !! 19
35345263800
The list will only get partially evaluated for the values you need.
You can also easily output a range of values:
> putStrLn $ unlines $ take 5 $ map (unwords . map show . take 5) $ pascal
1 1 1 1 1
1 2 3 4 5
1 3 6 10 15
1 4 10 20 35
1 5 15 35 70
Another option is to use your original function but memoize it using one of the various memorization libraries available. For example, using data-memocombinators:
import Data.MemoCombinators
pascal :: Integer -> Integer -> Integer
pascal = memo2 integral integral pascal'
pascal' :: Integer -> Integer -> Integer
pascal' 1 _ = 1
pascal' _ 1 = 1
pascal' x y = (pascal (x - 1) y) + (pascal x (y - 1))
The obvious choice for an infinite 2D "array" would be a nested list, i.e. an infinite list of infinite lists. It might thus be
pascal' :: [[Integer]]
pascal' = repeat 1 : [ 1 : [ pascalGen x y | y<-[1..] ] | x<-[1..] ]
where pascalGen x y = pascal' !! (x-1) !! y + pascal' !! x !! (y - 1)
This now has the function calls memoised. It's still not optimal because of list O (n) access, but not that bad either.
Related
--for number divisible by 15 we can get it easily
take 10 [x | x <- [1..] , x `mod` 15 == 0 ]
--but for all how do I use the all option
take 10 [x | x <- [1..] , x `mod` [2..15] == 0 ]
take 10 [x | x <- [1..] , all x `mod` [2..15] == 0 ]
I want to understand how to use all in this particular case.
I have read Haskell documentation but I am new to this language coming from Python so I am unable to figure the logic.
First you can have a function to check if a number is mod by all [2..15].
modByNumbers x ns = all (\n -> x `mod` n == 0) ns
Then you can use it like the mod function:
take 10 [x | x <- [1..] , x `modByNumbers` [2..15] ]
Alternatively, using math, we know that the smallest number divible by all numbers less than n is the product of all of the prime numbers x less than n raised to the floor of the result of logBase x n.
A basic isPrime function:
isPrime n = length [ x | x <- [2..n], n `mod` x == 0] == 1
Using that to get all of the primes less than 15:
p = [fromIntegral x :: Float | x <- [2..15], isPrime x]
-- [2.0,3.0,5.0,7.0,11.0,13.0]
Now we can get the exponents:
e = [fromIntegral (floor $ logBase x 15) :: Float | x <- p']
-- [3.0,2.0,1.0,1.0,1.0,1.0]
If we zip these together.
z = zipWith (**) p e
-- [8.0,9.0,5.0,7.0,11.0,13.0]
And then find the product of these we get the smallest number divisible by all numbers between 2 and 15.
smallest = product z
-- 360360.0
And now to get the rest we just need to multiply that by the numbers from 1 to 15.
map round $ take 10 [smallest * x | x <- [1..15]]
-- [360360,720720,1081080,1441440,1801800,2162160,2522520,2882880,3243240,3603600]
This has the advantage of running substantially faster.
Decompose the problem.
You already know how to take the first 10 elements of a list, so set that aside and forget about it. There are infinitely many numbers divisible by all of [2,15], your remaining task is to list them all.
There are infinitely many natural numbers (unconstrained), and you already know how to list them all ([1..]), so your remaining task is to transform that list into the "sub-list" who's elements are divisible by all of [2,15].
You already know how to transform a list into the "sub-list" satisfying some constraint (predicate :: X -> Bool). You're using a list comprehension in your posted code, but I think the rest of this is going to be easier if you use filter instead. Either way, your remaining task is to represent "is divisible by all of [2,15]" as a predicate..
You already know how to check if a number x is divisible by another number y. Now for something new: you want to abstract that as a predicate on x, and you want to parameterize that predicate by y. I'm sure you could get this part on your own if asked:
divisibleBy :: Int -> (Int -> Bool)
divisibleBy y x = 0 == (x `mod` y)
You already know how to represent [2,15] as [2..15]; we can turn that into a list of predicates using fmap divisibleBy. (Or map, worry about that difference tomorrow.) Your remaining task is to turn a list of predicates into a predicate.
You have a couple of options, but you already found all :: (a -> Bool) -> [a] -> Bool, so I'll suggest all ($ x). (note)
Once you've put all these pieces together into something that works, you'll probably be able to boil it back down into something that looks a little bit like what you first wrote.
I'm looking for a non-recursive implementation of sum of digits (a "cross sum") of a non-negative number like this:
cs :: Int -> Int
cs n = sum digits_of_n where digits_of_n = [ . | ... ]
Basically: How does one get a list of digits from a non-negative whole number using list comprehension only?
A cross sum example: The crossum of 157 is 1 + 5 + 7 = 13
The "usual way" would be extracting the digits from a number recursively using modulo and division, and then summing them up like this:
cs :: Int -> Int
cs n = if n == 0 then 0 else n `mod` 10 + cs (n `div` 10)
I have however difficulty expressing this without recursion and with list comprehension, does anyone have ideas regarding this?
sume n = foldr (+) 0 [ digitToInt c | c <- show n, isDigit c ]
Haskell allows to represent recurrent functions in a very concise way. For example, infinite list, that contains Fibonacci numbers can be defined as follows:
fibs :: [Integer]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
I am dealing with 'probabilists' Hermite polynomials, which have the following recursion relation:
What would be the optimal way to construct the infinite list of n-th Hermite polynomials for given x?
We can write it as:
hermite :: (Enum n, Num n) => n -> [n]
hermite x = s
where s#(_:ts) = 1 : x : zipWith3 (\hn2 hn1 n1 -> x*hn1 - n1*hn2) s ts [1..]
where the first items 1 : x : ... are the first elements of the hermite (you can fill in other values).
For the next one, we zip the original values s (so that starts with H0), the tail ts of s (that starts with H1) and the index (that starts with 2, 3, ...) and perform an operation x*hn1 - x*hn2 (nh1 stands for Hn-1, and nh2 stands for Hn-2), and so we calculate the next element each time.
The first 11 values for x = 0.75 are:
Prelude> take 11 (hermite 0.75)
[1.0,0.75,-0.4375,-1.828125,-5.859375e-2,7.2685546875,5.744384765625,-39.30303955078125,-69.68797302246094,262.1583366394043,823.8105096817017]
So the first value is 1, the second x, the third one x*x-2, the fourth one x*x*x-2*x-3*x, and so on.
That being said, if I recall correctly, the recursion formula of the Hermite polynomials is:
Hn(x) = 2×x×Hn-1(x)-2×(n-1)Hn-2(x)
instead of the one quoted in the question.
In that case the formula is thus:
hermite :: (Enum n, Num n) => n -> [n]
hermite x = s
where s#(_:ts) = 1 : 2 * x : zipWith3 helper s ts [1..]
helper hn2 hn1 n1 = 2 * (x * hn1 - n1 * hn2)
Then the first 11 values are:
Prelude> take 11 (hermite 0.75)
[1.0,1.5,0.25,-5.625,-9.9375,30.09375,144.515625,-144.3515625,-2239.74609375,-1049.994140625,38740.4384765625]
Which is correct acording to this Wolfram article:
H0 = 1
H1 = 2*x
H2 = 4˙x2 - 2
H3 = 8˙x3 - 4˙x
H4 = 16˙x4 - 48˙x2 + 12
Which maps exactly on the values we obtained:
Prelude> let x = 0.75 in [1,2*x,4*x*x-2,8*x*x*x-4*x,16*x*x*x*x-48*x*x+12]
[1.0,1.5,0.25,0.375,-9.9375]
Function Definitions:
first_threes :: [Int] -- first three numbers repeated
first_threes = 1:2:3:first_threes -- th.1
take :: Int -> [a] -> [a] -- take
take 0 _ = [] -- t.1
take n (x:xs) = x : (take (n - 1) xs) -- t.2
sum :: [Int] -> Int -- summation of an Int list
sum [] = 0 -- s.1
sum (x:xs) = x + (sum xs) -- s.2
I need to rewrite the statement below by using the definitions of the functions above. I need to obtain the answer 9. I need to justify each solution using 'Lazy Evaluation'.
Hugs_Main> my sum (my take 5 first_threes)
9
I am trying to work out 20 solutions which obtain 9 as the answer. Below are my first 10 solutions but I cannot think of anything else. Can anyone help out?
My first 10 solutions:
my_sum (my_take 5 first_threes)
my_sum (my_take 5 (1:2:3:first_threes))
my_sum (my_take 5 (1:2:first_threes))
my_sum (my_take 5 (2:first_threes))
my_sum (my_take 4 (3:first_threes))
my_sum (1:2:3:(my_take 2 (first_threes)))
my_sum (1:2:(my_take 3 (first_threes)))
my_sum (1:(2:my_take 3 (3:first_threes)))
my_sum (1:(my_take 4 (2:3:first_threes)))
my_sum (1:(my_take 4 (2:first_threes)))
I think this starts what your teacher wants to see
my_sum (my_take 5 first_threes)
-- th.1
my_sum (my_take 5 (1:2:3:first_threes))
-- t.2
my_sum (1 : my_take 4 (2:3:first_threes))
-- s.2
1 + my_sum (my_take 4 (2:3:first_threes))
-- continue yourself
A word on nomenclature: Check whether you have to work through solutions. I gave you a few rewrites. In every step you use one of the equalities to rewrite your term. The comments indicate which on I used for rewrite..
-- original expression
sum (take 5 first_threes)
-- (substitution) apply `take 5 first_threes` to `sum`
case take 5 first_threes of
[] -> 0
(x : xs) -> x + sum xs
-- pattern matching force evaluation of the first cons constructor so
-- we need eval `take 5 first_threes` first
-- apply `first_threes` to `take n` (substitution)
(\ n -> case n of
0 -> []
_ -> case first_trees of
_ -> []
(x : xs) -> x : take (n - 1) xs) 5
-- apply 5 to the lambda (substitution)
case 5 of
0 -> []
_ -> case first_trees of
_ -> []
(x : xs) -> x : take (5 - 1) xs
-- 5 is already in normal form, after case analysis we will have
case first_trees of
_ -> []
(x : xs) -> x : take (5 - 1) xs
-- pattern matching again (see above)
case 1 : 2 : 3 : first_threes of
_ -> []
(x : xs) -> x : take (5 - 1) xs
-- after case analysis (?) we will have
1 : take (5 - 1) (2 : 3 : first_threes)
-- now we return back to our original expression
case 1 : take (5 - 1) (2 : 3 : first_threes) of
[] -> 0
(x : xs) -> x + sum xs
-- after case analysis we will have
1 + sum (take (5 - 1) (2 : 3 : first_threes))
-- (+) operator is strict in both args
-- the first arg is already evaluated, but we also need to evaluate the second
1 + case take (5 - 1) (2 : 3 : first_threes) of
[] -> 0
(x : xs) -> x + sum xs
-- and so on...
-- in the end we will get
1 + (2 + (3 + (1 + (2 + (0)))))
-- which is evaluated in reverse order (starting from the `0`)
I'm new to Haskell and I really need some help!
I have to write a program that includes a recursive function to produce a list of binomial coefficients for the power n=12 using the Pascal's triangle technique.
I have some ideas in my head but because I'm just getting started I have no idea how to implement this to haskell?!
Could someone please help me out??
first row: (a+b)^0 = 1
second row: (a+b)^1 = 1a+1b
third row: (a+b)^2 = 1a^2+2ab+1b^2
and so on...this is my main idea. But I cant even try this out because I have no idea how I put this in Haskell..getting errors all the time
Start by assigning an index to each element in the triangle:
| 0 1 2 3 4 5 6
--+--------------------------
0 | 1
1 | 1 1
2 | 1 2 1
3 | 1 3 3 1
4 | 1 4 6 4 1
5 | 1 5 10 10 5 1
6 | 1 6 15 20 15 6 1
Here I've simply put the triangle on its side so that we can number them. So here I'd say that the element at (6, 4) is 15, whereas (4, 6) doesn't exist. Now focus on writing a function
pascal :: Integer -> Integer -> Integer
pascal x y = ???
Such that you can generate this version of the triangle. You can start by writing
pascal x y
| x == 0 = 1
| x == y = 1
| x < y = error "Not a valid coordinate for Pascal's triangle."
| otherwise = pascal ? ? + pascal ? ?
Note that here, instead of figuring out which elements should be added together by diagonals, you can do it via rectangular coordinates. Here, you'll note that y is which row in the triangle you're on and x is the position of the element in that row. All you need to do is figure out what goes in place of the ?s.
Once you get that working, I've got a one-liner for this triangle that is more efficient and can generate the entire triangle all at once while still using recursion:
import Data.List (scanl1)
pascals :: [[Integer]]
pascals = repeat 1 : map (scanl1 (+)) pascals
Don't try turning this solution in to your professor, it's not what they're looking for and it would make it pretty obvious someone gave you this solution if you've only been doing Haskell for a week. However, it really shows how powerful Haskell can be for this sort of problem. I would show how to index pascals to get a given (n, k) value, but doing so would also give you too many hints for solving the naive recursion.
Since there's been some confusion, the reason why I gave this solution is to draw a parallel between it and the often shown lazy implementation for the Fibonacci sequence:
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
Compared to
fib 0 = 1
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
This definition generates an infinite list of all the Fibonacci numbers, and does so quite efficiently (from the point of view of the CPU, RAM is a different story). It encodes in its first 2 elements the base case, then a recursive expression that can calculate the rest. For the Fibonaccis, you need 2 values to start you off, but for Pascal's triangle, you only need one value, that value just happens to be an infinite list. There is an easy to see pattern going across the columns in the grid I posted above, the scanl1 (+) function just takes advantage of this pattern and allows us to generate it very easily, but this is generating the diagonals of the triangle rather than the rows. To get the rows, you can index this list, or you can do some fancy tricks with take, drop, and other such functions, but that's an exercise for another day.
Start out with the triangle itself:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
...
You should notice that to write down the next row, you must apply this rule: sum the previous rows' adjacent elements, using a 0 for the lonely edge elements. Visually:
0 1 0
\+/ \+/
0 1 1 0
\+/ \+/ \+/
0 1 2 1 0
\+/ \+/ \+/ \+/
1 3 3 1
...
Operationally, that looks like this:
For row 0:
[1] (it's a given; i.e. base case)
For row 1:
[0, 1] <- row 0 with a zero prepended ([0] ++ row 0)
+ +
[1, 0] <- row 0 with a zero appended (row 0 ++ [0])
= =
[1, 1] <- element-wise addition
For row 2:
[0, 1, 1]
+ + +
[1, 1, 0]
= = =
[1, 2, 1]
Generally, for row N:
element-wise addition of:
[0] ++ row(N-1)
row(N-1) ++ [0]
Remember that element-wise addition of lists in Haskell is zipWith (+).
Thus we arrive at the following Haskell definition:
pascal 0 = [1]
pascal n = zipWith (+) ([0] ++ pascal (n-1)) (pascal (n-1) ++ [0])
Or in a fashion similar to the famous "lazy fibs":
pascals = [1] : map (\xs -> zipWith (+) ([0] ++ xs) (xs ++ [0])) pascals
Another possible solution (more suitable for beginners in my opinion):
pascal :: Integer -> [Integer]
pascal 0 = [1]
pascal 1 = [1, 1]
pascal n = let p = pascal (n - 1)
in [1] ++ pascalStep p ++ [1]
pascalStep :: [Integer] -> [Integer]
pascalStep [] = []
pascalStep [_] = []
pascalStep (x:y:xs) = x + y : pascalStep (y : xs)
Using let to avoid more space usage.
pascal is calling recursively to find all previous rows, using them to get the next row, until getting to the desired row.
Output:
*Main> pascal 3
[1,3,3,1]
*Main> pascal 4
[1,4,6,4,1]
*Main> pascal 5
[1,5,10,10,5,1]
Start with the base case.
pascal 0 0 = 1
Then handle the edge cases
pascal n 0 = 1
pascal n r | n == r = 1
Now expand with the recursive step
pascal n r = pascal (n - 1) (r - 1) + pascal (n - 1) r
If you want the list for a specific row, write a wrapper
binom n = map (pascal n) [0..n]
Figuring out the types shouldn't be hard
pascal :: Integral a => a -> a -> a
binom :: Integral a => a -> [a]
I'm on my phone so please excuse the mistakes, but you can use Haskell's lazy evaluation in a really cool way here.
pascals :: [[Int]]
pascals = [1]:map (\r -> zipWith (+) (0:r) (r++[0])) pascals
Which you could make point free with a fork but it's rather esoteric.
pascals :: [[Int]]
pascals = [1]:map ((zipWith (+) -<) (0:) (++[0])) pascals
But I personally really like this code, and thinks it's worth being readable-
pascals :: [[Int]]
pascals = [1]:map next pascals
where next = (zipWith (+) -<) (0:) (++[0])
But combinators like that can get a bit confusing, no matter how much I like point free programming.