1

im trying to get the kth row in every list in the pascal list. For example pascal 4 would get the 4nd element in every row. So it would return 1,4,10,20... etc. I understand how to construct an infinite pascal list which is what outputs below, but im unsure of how to get a nth element in each nested list. any suggestions? i was thinking of using map, but im not necessarily mapping a function here which is throwing me off a bit. thank you.

// im trying to get pascal k to return the nth element of every row in the triangle
pascal n = map(\n -> ??) take n pascal 
pascal_infite = [1] : map (\l -> zipWith (+) (l ++ [0]) (0:l)) pascal_infinite
helloworld
  • 181
  • 3
  • 12

2 Answers2

2

To get the kth row:

>>> pascal_infinite !! 4
[1,4,6,4,1]

To get all rows from [0..k]:

>>> map (pascal_infinite !!) [0..4]
[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]

To get all rows from [0..k] fast:

>>> take (4+1) pascal_infinite
[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]

Whoops, misread the question a bit. To get what you're asking for, you should probably construct just use the good old n choose k formula or something similar if you're concerned about speed.

If this is just an exercise, disregarding speed, here's one way:

pascal n = map (!! n) $ drop n pascal_infinite

Then simply sample a couple of the 4th elements:

>>> take 8 $ pascal (4-1)
[1,4,10,20,35,56,84,120]
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
1

This basically is an iterate :: (a -> a) -> a -> [a] function where you have a state, and each time you update the state and you thus produce a list of elements.

As iterate function, we basically want to perform a zipWith (+) with the previous list xs, and (0:xs), but where we keep iterating until both lists are exhausted. We can implement a zipWithLongest for this:

zipWithLongest :: a -> b -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithLongest x0 y0 f = go
    where go (x:xs) (y:ys) = f x y : go xs ys
          go [] t = map (f x0) t
          go t [] = map (flip f y0) t

So now we can produce the list by using:

import Control.Monad(ap)

pascalTriangle :: Num n => [[n]]
pascalTriangle = iterate (ap (zipWithLongest 0 0 (+)) (0:)) [1]

We can index the list by using the (!!) :: [a] -> Int -> a. Note however that this is usually a bit of an anti-pattern because of two reasons:

  1. a lookup takes O(k) time with k the value of the index we want to obtain; and
  2. it is a partial function in the sense that the index can be out of range (here a negative index, and for finite lists an index that is too large).

We know that every next line of the Pascal triangle contains one element more than the previous line. So the k-th line contains k elements. If we want to obtain the k-th element of every sublist, then we should first ignore all the lists that don't have a k-th element. So we use drop k to drop the first k-elements of the list, and then a map (!! k) to obtain the k-th element of every sublist that we do not filter.

So we can write a function:

kThPascalTriangle :: Num n => Int -> [n]
kThPascalTriangle k = map (!! k) (drop k pascalTriangle)
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555