I wanted to build an artistic way of displaying Pascall's Triangle. I have been on a sort of math kick lately playing with various cool formulas and converting them to code to display them in web-pages.
Here is a live version (note: you will need to scroll your browser right to see the result) and here is my full source on GitHub.
We start off with a function in PHP I called pt:
/** * @param int an uneven integer * @return array * */ function pt($w) { if(gettype($w / 2) == 'integer') { die("\nthe number must be odd\n"); } // x , y variables for drawing the triangle $px = 1; $py = 1; // (n choose k) $n = 0; $k = 0; // n // --- // d $numerator = 0; $denominator = 0; $out = array(); while($py <= $w) { for($px=1;$px<=$w;$px++) { if($px <= (($w - $py) / 2)) { $out[$px][$py] = null; $n = 0; }elseif($px > ((($w - $py) / 2)+$py)){ $out[$px][$py] = null; $n = 0; }else{ // n = k! $numerator = factorial($k); // d = n!(k - n)! $denominator = factorial($n) * factorial($k - $n); // r = n // - // d $result = $numerator / $denominator; // add result to the array $out[$px][$py] = $result; // increment n $n++; } } $k++; $py++; } return $out; }
I am using the method (n choose k) to find each value in the triangle:
(n k) = n! / k!(n - k)!
To automate the operation I created a function called factorial that does just what its name implies.
/** * returns the factorial of an integer * example: 4 = 4 * 3 * 2 * 1; * @param int * @return int * */ function factorial($n) { // init the return $r = 1; for($f = 1; $f <= $n; $f++) { $r = $r * $f; } return $r; }
This is all that's necessary to actually create an array of values, but I want to be able to display the result...and what's more I wanted it to look cool.
The code returned from the function pt() alone could be exported as a JSON string (Ajax) and then rendered using Javascript.
But, I won't do something so dramatic here...I'll just export the value as a table and manipulate it a bit post-render.
So, next I add the body to my HTML document, add a table. And then call the function, looping the result and create a table.
<body> <img src="p-tri-title.png" /> <table> <?php $fs = 40; // build the table $r = pt(65); // loop the x part of the array for($x = 0; $x < count($r); $x++) { // open a row echo '<tr style="font-size:'.$fs.'px">'; $fs--; // loop the y part of the array for($y = 0; $y < count($r[$x]); $y++) { // reverse the coords ( or the trinagle will appear sideways) // also check if null ( if NOT then render number ) echo '<td>'.((null !== $r[$y][$x]) ? number_format($r[$y][$x],0,'','') : '').'</td>'; } // close the row echo '</tr>'; } ?> </table> </body> </html>
At this point the program can be ran and will create a triangle.
Pretty good...But we can do better.
Pascall's triangle not only looks cool. Its an effective table of exponents. A natural logarithm table. So, let's stagger each row so that the content is correct.
The easiest way to do this is with a little CSS
tr:nth-child(even) td { position: relative; left: -1%; }
The previous code says that for every "even" row, we want the table cell to be moved over by -1% of the table width.
Now we can add some color, shadows and typography:
body { color: #94d3ff; text-shadow: 1px 1px 16px rgba(0, 0, 0, 0.41); font-family: Arial; font-size: 10px; background: rgb(37,141,200); background: -moz-linear-gradient(top, rgba(37,141,200,1) 0%, rgba(37,141,200,1) 38%, rgba(27,102,142,1) 100%); background: -webkit-linear-gradient(top, rgba(37,141,200,1) 0%,rgba(37,141,200,1) 38%,rgba(27,102,142,1) 100%); background: linear-gradient(to bottom, rgba(37,141,200,1) 0%,rgba(37,141,200,1) 38%,rgba(27,102,142,1) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#258dc8', endColorstr='#1b668e',GradientType=0 ); } body > img { position: fixed; z-index: 9999; margin: 10px; right: 0; top: 0; } table { position: relative; left: -80%; } td { text-align: center; }
Lastly, we will add a little Javascript. I am using jQuery...Its easier.
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"> <script type="text/javascript"> /** * Some Javascript to format the triangle in HTML * @binding jQuery */ $(document).ready(function(){ var td = 0; // loop evey row $('tr').each(function(){ td = 0; // set a base width for the row var mxw = 0; // loop each cell on this row $(this).find('td').each(function(){ td++; // if this cell is the widest, then set it as the max if($(this).width() > mxw) { mxw = $(this).width(); } }); // set all the cells as the same width (max) $(this).find('td').css('width',mxw); }); }); </script>
This last bit of Javascript loops through each cell of each row of the table and for each row it asks if this cell is wider than the previous cell. If 'true' then set this cells width as the max. Then for each row set the all cell width to the maximum width for that row.