Skip to content

Instantly share code, notes, and snippets.

@edrex
Created February 27, 2012 02:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save edrex/1920883 to your computer and use it in GitHub Desktop.
Save edrex/1920883 to your computer and use it in GitHub Desktop.
Pascal's Triangle Congruence Mod p
<!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>
<link href="style.css" media="screen" rel="stylesheet" type="text/css" />
<body>
<div style="float:right; text-align: right">
<form id='form'>
<p>
<label for="max">Rows</label>
<input type="number" value="64" min="1" max=500 id="n">
</p>
<p>
<label for="max">P</label>
<input type="number" value="11" min="1" max=500 id="p">
</p>
<input type="submit" value="Generate!"/>
</form>
</div>
<script src="pascal.js" type="text/javascript"></script>
<script>
var update = pascal.create(d3.select('body'))
function render() {
update(d3.select("#n").property("value"),
d3.select("#p").property("value"));
}
render();
var form = d3.select("#form")
.on("submit", function() {
render()
d3.event.preventDefault()
});
</script>
// pascal module
var pascal = (function(){
var calculate = function(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;
}
return {
calculate: calculate,
create: function(parent) {
var colors = d3.interpolateHsl('rgb(0,255,0)', 'rgb(128, 0, 128)');
var ratio = Math.sin(Math.PI/3),
height = 500
var width = height/ratio
var svg = parent.append("svg")
.attr("class", 'pascal')
.attr("width", width)
.attr("height", height)
var vis = svg.append("g")
// after binding returns an update method
var update = function(n, p) {
var n = Math.min(n, width-2)
var vis_width = (n/(n+2)) * width,
vis_height = (n/(n+2)) * height
var x_margin = (width - vis_width)/2,
y_margin = (height - vis_height)/2
var u = 10 // unit size
var scale = vis_width/(n*u)
vis.attr("transform", "translate("+ (vis_width/2+x_margin) +","+ y_margin +") scale("+scale+","+scale+")")
var ur = vis.selectAll('g.row')
.data(calculate(n, p))
ur.enter().append('g')
.attr('class', 'row')
.attr('transform', function(d,i){return "translate("+ -i*u/2 +","+ i*u*ratio +")"})
ur.exit().remove()
var ue = ur.selectAll('circle')
.data(function(d) { return d })
ue.enter().append("circle")
.attr("r", u/2)
.attr("cx", function(d,i){return i*u})
.append("title")
ue.style("fill", function(d) {return colors((d%p)/p)})
.select("title")
.text(function(d, i) { return ""+d });
}
return update;
}
}
})();
body {
margin: 0 40px;
}
form#form {
font-size: small;
}
circle:hover {
cursor:crosshair;
fill: red ! important;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment