Skip to content

Instantly share code, notes, and snippets.

@ex
Created September 23, 2012 02:15
Graphic display of problem Euler 393 with (n = 8)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Euler 393</title>
</head>
<body>
<div style="text-align: center;">
<canvas height="902" id="canvas" width="660"></canvas></div>
<script type="application/javascript">
var count; // number of final positions
var N; // total cells in the board
var n; // grid partition
var canvas;
var ctx;
function dfs(now, next) {
for (var k = 0; k < N; k += 1) {
// Find an ant to move.
if (now[k] > 0) {
// Try to move it to the right.
if ((k % n < n - 1) && (next[k + 1] == 0)
&& ((next[k] == 0) || (next[k] != now[k] + 1))) {
next[k + 1] = now[k];
now[k] = 0;
dfs(now, next);
now[k] = next[k + 1];
next[k + 1] = 0;
}
// Try to move it to the left.
if ((k % n > 0) && (next[k - 1] == 0)
&& ((next[k] == 0) || (next[k] != now[k] - 1))) {
next[k - 1] = now[k];
now[k] = 0;
dfs(now, next);
now[k] = next[k - 1];
next[k - 1] = 0;
}
// Try to move it up.
if ((k >= n) && (next[k - n] == 0)
&& ((next[k] == 0) || (next[k] != now[k] - n))) {
next[k - n] = now[k];
now[k] = 0;
dfs(now, next);
now[k] = next[k - n];
next[k - n] = 0;
}
// Try to move it down.
if ((k < N - n) && (next[k + n] == 0)
&& ((next[k] == 0) || (next[k] != now[k] + n))) {
next[k + n] = now[k];
now[k] = 0;
dfs(now, next);
now[k] = next[k + n];
next[k + n] = 0;
}
// We don't need to consider the other ants. The above exploration
// has already found all the other possibilities.
break;
}
}
// Check if the position is valid.
for (var i = 0; i < N; i += 1) {
if (next[i] == 0) {
return;
}
}
// Draw position.
drawBoard(82 * (count % 8), 82 * Math.floor(count / 8), 18, 18, 1, next);
// We implemented the DFS exploration in such a way that if we got here
// we must have a valid final position. So we increase the counter.
count += 1;
}
function euler_393(size) {
count = 0;
n = size;
N = n * n;
// This array holds the ants that need to be moved.
var now = [];
// This array holds the ants that have already been moved.
var next = [];
// Initialize positions, 0 is empty.
for (var k = 0; k < N; k += 1) {
now[k] = k + 1;
next[k] = 0;
}
// Use Depth First Search to compute the number of possible ways.
dfs(now, next)
}
function drawCell(x, y, w, h, c) {
switch(c) {
case 0: ctx.fillStyle = "rgb(66, 46, 71)"; break;
case 1: ctx.fillStyle = "rgb(77, 87, 117)"; break;
case 2: ctx.fillStyle = "rgb(181, 120, 9)"; break;
case 3: ctx.fillStyle = "rgb(128, 106, 42)"; break;
case 4: ctx.fillStyle = "rgb(0, 255, 221)"; break;
case 5: ctx.fillStyle = "rgb(77, 170, 189)"; break;
case 6: ctx.fillStyle = "rgb(250, 155, 0)"; break;
case 7: ctx.fillStyle = "rgb(255, 204, 51)"; break;
case 8: ctx.fillStyle = "rgb(250, 181, 135)"; break;
case 9: ctx.fillStyle = "rgb(247, 139, 106)"; break;
case 10: ctx.fillStyle = "rgb(171, 217, 4)"; break;
case 11: ctx.fillStyle = "rgb(234, 242, 5)"; break;
case 12: ctx.fillStyle = "rgb(235, 42, 55)"; break;
case 13: ctx.fillStyle = "rgb(242, 90, 73)"; break;
case 14: ctx.fillStyle = "rgb(114, 166, 3)"; break;
default: ctx.fillStyle = "rgb(70, 115, 2)"; break;
}
ctx.fillRect(x, y, w, h);
}
function drawBoard(x, y, w, h, d, board) {
for (var k = 0; k < 16; ++k) {
drawCell(x + (k % 4) * (w + d), y + Math.floor(k / 4) * (h + d),
w, h, board[k] - 1);
}
}
canvas = document.getElementById("canvas");
if (canvas.getContext) {
ctx = canvas.getContext("2d");
euler_393(4);
console.log("TOTAL:" + count);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment