Re: Equilateral Pascal's Triangle in perltex
by Perlbotics (Archbishop) on Jun 01, 2009 at 17:42 UTC
|
use strict;
sub pascalMatrix {
my $tabularRows = "";
my @row = (1);
my $cols = ($_[0] * 2) + 1; #add: final number of columns
my $filler = "{ }"; #add: used to mark an empty entry
for (my $r = 0; $r <= $_[0]; $r++) {
# Output the current row
### begin of modification
# insert a filler between each item (sprintf is for LaTeX cosmeti
+cs)
my @fmt = map { (sprintf("%3d",$_), $filler) } @row; pop @fmt;
# pre-/append a filler until final number of columns reached
unshift(@fmt,$filler), push(@fmt,$filler) while (@fmt < $cols);
$tabularRows .= join (" & ", @fmt) ." \\\\\n";
### end of modification
# Generate the next row
my @nextRow = (1);
for (my $c = 1; $c <= $r; $c++) {
push @nextRow,
@row[$c - 1] + @row[$c];
}
push @nextRow, 1;
@row = @nextRow;
}
return
"\\begin{tabular}{*{$cols}{c}c}\n" . # changed!
$tabularRows .
"\\end{tabular}\n";
}
print pascalMatrix(10);
This was the output of the original version:
\begin{tabular}{*{5}{c}c}
1 \\
1&1 \\
1&2&1 \\
1&3&3&1 \\
1&4&6&4&1 \\
1&5&10&10&5&1 \\
\end{tabular}
This is the output of the patched version:
\begin{tabular}{*{11}{c}c}
{ } & { } & { } & { } & { } & 1 & { } & { } & { } & { } & { } \\
{ } & { } & { } & { } & 1 & { } & 1 & { } & { } & { } & { } \\
{ } & { } & { } & 1 & { } & 2 & { } & 1 & { } & { } & { } \\
{ } & { } & 1 & { } & 3 & { } & 3 & { } & 1 & { } & { } \\
{ } & 1 & { } & 4 & { } & 6 & { } & 4 & { } & 1 & { } \\
1 & { } & 5 & { } & 10 & { } & 10 & { } & 5 & { } & 1 \\
\end{tabular}
My LaTeX installation is gone, but there's a nice
LaTeX Online-Compiler available.
HTH
Update: The code presented above is a runnable Perl program. In order to make it work with LaTeX you need to get rid of use strict; and print pascalMatrix(10);. Furthermore, replace
sub pascalMatrix by \perlnewcommand{\pascalMatrix}[1].
Remove, rename, or uncomment the previous version of \pascalMatrix.
| [reply] [d/l] [select] |
|
|
\documentclass{article}
\usepackage{perltex}
\perlnewcommand{\pascalMatrix}[1] {
my $tabularRows = "";
my @row = (1);
my $cols = ($_[0] * 2) + 1; #add: final number of columns
my $filler = "{ }"; #add: used to mark an empty entry
for (my $r = 0; $r <= $_[0]; $r++) {
# Output the current row
### begin of modification
# insert a filler between each item (sprintf is for LaTeX cosmeti
+cs)
my @fmt = map { (sprintf("%3d",$_), $filler) } @row; pop @fmt;
# pre-/append a filler until final number of columns reached
unshift(@fmt,$filler), push(@fmt,$filler) while (@fmt < $cols);
$tabularRows .= join (" & ", @fmt) ." \\\\\n";
### end of modification
# Generate the next row
my @nextRow = (1);
for (my $c = 1; $c <= $r; $c++) {
push @nextRow,
@row[$c - 1] + @row[$c];
}
push @nextRow, 1;
@row = @nextRow;
}
return
"\\begin{tabular}{*{$cols}{c}c}\n" . # changed!
$tabularRows .
"\\end{tabular}\n";
}
\begin{document}
\pascalMatrix{10}
\end{document}
| [reply] [d/l] [select] |
|
|
Thank you so much for your reply!
I tried running the code you posted with perltex, but it gives the following errors
(1)Undefined control sequence
(2)end occured inside a group at level 3.
This is probably some stupid mistake, but I just can't figure it out.
| [reply] |
Re: Equilateral Pascal's Triangle in perltex
by Corion (Patriarch) on Jun 01, 2009 at 16:05 UTC
|
If you know how wide your triangle will be at the bottom, it shouldn't be too hard for you to indent the numbers at the top so that half of the numbers are left of the middle and half of them are to the right. As you are certainly aware (and a short induction shows), the count of numbers increases by one for each row you add to the bottom. The width of each number can be determined either experimentally or estimated. You will then need to output ($count_of_numbers * $number_width - $number_width_of_first_number_in_the_triangle) /s spaces to align the first row to the center, then output the first row. Then repeat the calculation for the second row of the triangle and output as many spaces as necessary before printing the numbers in the second row.
| [reply] [d/l] |
Re: Equilateral Pascal's Triangle in perltex
by zentara (Cardinal) on Jun 01, 2009 at 16:19 UTC
|
I didn't check out the pdf, but using a Tk::Canvas, Tk::Zinc, Gnome2::Canvas, or the Goo Canvas would make it simple. A simple trick to remember, is that an equilateral triangle, must be equi-angular.
| [reply] |
Re: Equilateral Pascal's Triangle in perltex
by Khen1950fx (Canon) on Jun 02, 2009 at 00:07 UTC
|
This might help you:
Pascal's Triangle. It has a couple of interactive versions that'll help you visualize what's going on.
Update: I've been looking for a couple of hours, just to satisfy my curiosity, and I finally found it. See Tie::Math under the "How about Pascal's Triangle" section:
#!/usr/bin/perl
use Tie::Math qw(f X Y);
my %pascal;
tie %pascal, 'Tie::Math', sub {
if( X <= Y and Y > 0 and X > 0 ) {
f(X,Y) = f(X-1,Y-1) + f(X,Y-1);
}
else {
f(X,Y) = 0;
}
},
sub {
f(1,1) = 1;
f(1,2) = 1;
f(2,2) = 1;
};
#'#
my $height = 5;
for my $y (1..$height) {
print " " x ($height - $y);
for my $x (1..$y) {
print $pascal{$x,$y};
}
print "\n";
}
Update: fixed, added comma after "Tie::Math" line 6 and right curly on line 12.
| [reply] [d/l] |
|
|
Thank you everyone for your helpful advice!
However, I am still struggling.
I should have perhaps made my level of abilities more clear: when it comes to perl, I know absolutely nothing! The only thing I know is, that one is supposed stick the code into a text editor, stick the LaTeX commands around it, and then run it with perltex. Evidently, with code posted by Perlbotics, I am supposed to do something far more advanced?
| [reply] |
|
|
Back to my suggestion of using an advanced Canvas type widget.........
On most canvases you can rotate items, so imagine this construction technique for equilateral triangles.
Create 3 identical line segments, stacked right on top of each other. Leave the bottom
segment as is. The next segment is then rotated around its left end point, x degrees, in a counterclockwise direction. The last segment is rotated clockwise around its right endpoint, x degrees. The whole segment set can be a "group", and the resulting triangle can be translated (moved) as a group, and rotated to any angle.
Calculating the x degree value depends on the original line segment lengths chosen, and can be calculated with some simple trig. Of course, for an equilateral triangle, it's just 60 degrees.
BTW, Coach, are you trying to find a way to make "play diagrams" for a team? :-) If so, you might want to check out Tk Patio/Office layout designer
| [reply] |
|
|
|
|
Re: Equilateral Pascal's Triangle in perltex
by Limbic~Region (Chancellor) on Jun 02, 2009 at 14:10 UTC
|
Coach,
I know what you are looking for is a quick solution to your problem so you can move on. There are plenty of images of Pascal's Triangle that can be found on google or web apps that generate them. Since you are student and your job is to learn, I will tell you how I would do it programmatically if it were me.
The first thing I would do is ask how many rows the user wanted to generate. This will tell me two pieces of valuable information. The first is what the largest number in the triangle will be. If you are not sure why this is, I will remind you of the relationship between Pascal's Triangle and combinatorials (C = N choose K). The second piece of information is how many leading units you need for the first row. What do you mean by unit you ask - read on.
The next thing I would do is determine the length of the largest number in the triangle. This will become 1 unit. Every value (space or number) will be this wide. This will make the triangle look as smooth as possible (assuming monospace font).
Finally, I would start filling in each row. Filling up the leading white space units and then placing each number. Each number will need to be centered in the unit - probably using sprintf. If the triangle still does not look smooth it is probably a result of imperfect centering. You may be able to remedy this by varying which side to leave the extra space on (round robin, random, odd/even, etc).
You probably already have your solution and have moved on but if you would like to really spend some time learning perl - please feel free to ask questions and we will help you out as best as we can.
| [reply] |