User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the Legacy and Other Languages section within the Software Development category of DaniWeb, a massive community of 363,801 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 4,537 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our Legacy and Other Languages advertiser:

Pascal's Triangle

Join Date: Feb 2008
Posts: 8
Reputation: DevonMcC++ is an unknown quantity at this point 
Rep Power: 0
Solved Threads: 1
DevonMcC++ DevonMcC++ is offline Offline
Newbie Poster

Re: Pascal's Triangle

  #6  
May 9th, 2008
I suppose anything is cryptic if you make no effort to understand it.

Even so, your statement is very odd. Apparently you are under the mis-apprehension that your failure to understand is the fault of a succinct, powerful notation and this means that the language was "deliberately" designed to be hard to understand.

Why would you even think something like this? I mean, why would someone deliberately make something difficult to understand? Most people I know strive for clarity. Do you think that "1+1" is cryptic because it uses a symbol "+" instead of the word "plus"? I suppose it is if you don't know math.

The other odd thing you seem to imply is that avoiding hard, unnecessary work is a bad thing. So, you're against the idea of carefully designed, well-tested, powerful, pre-written functions that you can combine in a clear, logically consistent manner?

This is all the more puzzling as your initial answer
join (table comb) [0..] apparently very closely resembles the J solution of
i. !/ i. because each "i." generates a vector of consecutive integers and "/" - similarly to (table comb) - combines these vectors in a table using "!". The "!" function, with a right and left arguments x and y returns the number of ways x things can be chosen from y possibilities - pretty much a direct statement of what you are doing when determining the coefficient of a polynomial expansion.

There are, of course other ways to do this more algorithmically and less mathematically as you appear to show in your final example. I say "appear" because that example is rather cryptic insofar as it uses the pre-written function "zipWith".

In J, I could write something I presume is similar to this:
pascalNewRow=: 3 : '1,(2+/\y),1' based on the following rule for generating a new row of the triangle from the previous one: start and end with 1; add together adjacent pairs for the middle section. The above expression "2+/\" adds together each adjacent 2 numbers across the first dimension of an array; the "3 :" defines a function. Once you know that, the code is a straightforward expression of the rule.

Similarly to the final expression in Haskell, we iterate the function "pascalNewRow" by using an iterator expressed by some symbols, "^:" instead of the word "iterate". So, the expression
pascalNewRow^:10 ] 1 returns the first ten rows of Pascal's triangle (starting with a "seed" of 1).

I find this much less cryptic than the Haskell expression but, of course, I've made the effort to understand it.

In any case, this has wandered far off topic. Why don't I conclude by giving a solution to the original problem? Taking my J code as a template, start by defining a function to add adjacent pairs of a vector:
int *addAdjacentPairs( int vlen, int *vec)
{   int vc, win2[2];
    win2[0]=0;
    win2[1]=vec[0];
    for(vc=0;vc<=vlen;vc++)
    {   vec[vc]=win2[0]+win2[1];
        win2[0]=win2[1];
        win2[1]=vec[vc+1];
    }
// Danger: returned vector is 1 longer than input: allocate accordingly.
    return 0;
}
and simply use it in a loop:
// PascalTriangle.c: print some rows of Pascal's triangle.

#include<stdio.h>

int main(void)
{   int vec[21];
    int ii,vc,nn;
    printf("How many lines (up to 20) do you want? ");
    scanf("%d",&nn);
// Should verify result and handle errors but this is why I don't like these
// languages that don't handle arrays natively so I won't bother.
    printf("\n");

    for(ii=0;ii<nn;ii++)
    {   vec[ii]=1;
        for(vc=0;vc<=ii;vc++) printf("%i ",vec[vc]);
        printf("\n");
        addAdjacentPairs( ii, vec);
     }
    return 0;
}

This provides a nice example of how solving the problem with a high-level notation leads to a more elegant solution even in a lower-level language.

Originally Posted by sarehu View Post
That's because J is deliberately cryptic and hides all the hard work behind pre-written combinators and functions, in this case ! being "choose". Given the equivalent of these two defined in Haskell:

comb n k = foldl' (\x y -> ((n - x + 1) * y) `div` x) 1 [1..k]

table f xs ys = foldr ((:) . (`map` ys) . f) [] xs

Then producing Pascal's triangle is as simple as join (table comb) [0..] .

But overall a much simpler solution is
iterate (\xs -> zipWith (+) (0:xs) (xs++[0])) [1]
Reply With Quote  
All times are GMT -4. The time now is 11:16 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC