Created
February 27, 2012 02:34
-
-
Save edrex/1920883 to your computer and use it in GitHub Desktop.
Pascal's Triangle Congruence Mod p
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <title>Pascal's Triangle Congruence Mod p</title> | |
| <script src="http://cdnjs.cloudflare.com/ajax/libs/d3/2.7.4/d3.min.js"></script> | |
| <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.1/underscore-min.js"></script> | |
| <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> | |
| <script src="http://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script> | |
| <style> | |
| form#form { | |
| font-size: small; | |
| } | |
| svg { | |
| font: 10px sans-serif; | |
| } | |
| circle:hover { | |
| cursor:crosshair; | |
| fill: red ! important; | |
| } | |
| .pascal-text { | |
| text-align: center; | |
| } | |
| .pascal-text div { | |
| white-space: nowrap; | |
| height: 5px; | |
| } | |
| .pascal-text div span { | |
| display: inline-block; | |
| width: 5px; | |
| height: 5px; | |
| margin: 0; | |
| } | |
| .axis path, .axis line { | |
| fill: none; | |
| stroke: #fff; | |
| } | |
| } | |
| </style> | |
| <body> | |
| <div style="float:right; text-align: right"> | |
| <form id='form'> | |
| <p> | |
| <label for="max">Maximum rows:</label> | |
| <input type="number" value="64" min="1" max=500 id="n"> | |
| </p> | |
| <p> | |
| <label for="max">P (base for mod):</label> | |
| <input type="number" value="11" min="1" max=500 id="p"> | |
| </p> | |
| <input type="submit" id="generate">Generate!</input> | |
| </form> | |
| </div> | |
| <script> | |
| function pascals_triangle(n, mod) { | |
| var T = [[1]]; | |
| var r=0 | |
| var f_no_mod = function(i) {return ((T[r-1][i-1]||0) + (T[r-1][i]||0))}; | |
| var f = mod ? function(i) { return f_no_mod(i) % mod } : f_no_mod; | |
| while (r < n-1) { | |
| r++ | |
| T.push(_.map(_.range(r+1), f)); | |
| } | |
| return T; | |
| } | |
| // flatten positional information into each entry so they can lay themselves out | |
| function mangle(T) { | |
| var R = []; | |
| for (var i=0; i<T.length; i++) { | |
| for (var j=0; j<T[i].length; j++) { | |
| R.push([i,j,T[i][j]]); | |
| } | |
| } | |
| return R; | |
| } | |
| var colors = d3.interpolateHsl('rgb(0,255,0)', 'rgb(128, 0, 128)'); | |
| var body = d3.select('body') | |
| function make_vis_text(n, p) { | |
| body.selectAll('.pascal-text').remove() | |
| var c = body.append('div') | |
| .attr('class', 'pascal-text'); | |
| c.selectAll('div').remove(); | |
| var row = c.selectAll('div') | |
| .data(pascals_triangle(n), function(n) {return n.length}); | |
| row.enter().append("div"); | |
| row.exit().remove(); | |
| var entry = row.selectAll('span') | |
| .data(function(d) { return d; }) | |
| .enter().append("span") | |
| //.text(function(d) { return d}) | |
| .style("background-color", function(v) {return colors((v%p)/p)}); | |
| } | |
| function make_vis_svg(n, p) { | |
| var canvas_size = 500 | |
| var n = Math.min(n, canvas_size-2); | |
| var vis_size = (n/(n+2)) * canvas_size | |
| var margin = (canvas_size - vis_size)/2 | |
| var scale = vis_size/n | |
| var dy = Math.sin(Math.PI/3) | |
| body.selectAll('.pascal-svg').remove() | |
| var svg = d3.select("body").append("svg") | |
| .attr("class", 'pascal-svg') | |
| .attr("width", canvas_size) | |
| .attr("height", canvas_size) | |
| var vis = svg.append("g") | |
| .attr("transform", "scale("+scale+","+scale+") translate("+(1+n/2)+",1.5) ") | |
| var entry = vis.selectAll('circle') | |
| .data(mangle(pascals_triangle(n, p)), function(n) {return n.length}); | |
| entry.enter().append("circle") | |
| .style("fill", function(d) {return colors((d[2]%p)/p)}) | |
| .attr("r", 0.5) | |
| .attr("cx", function(d){return d[1] - d[0]/2}) | |
| .attr("cy", function(d){return d[0]*dy}) | |
| .append("svg:title") | |
| .text(function(d, i) { return "The value at row "+d[0]+" and column "+ d[1]+ " is "+d[2] }); | |
| } | |
| function make_p_gen(p, g) { | |
| return make_vis_svg(Math.pow(p,g),p) | |
| } | |
| function render() { | |
| make_vis_svg(d3.select("#n").property("value"), | |
| d3.select("#p").property("value")); | |
| } | |
| render(); | |
| var form = d3.select("#form") | |
| .on("submit", function() { | |
| render() | |
| d3.event.preventDefault() | |
| }); | |
| //make_p_gen(3,4); | |
| </script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment