3.1 KiB
id | title | challengeType | forumTopicId |
---|---|---|---|
5a23c84252665b21eecc7ed5 | Knight's tour | 5 | 302297 |
--description--
Knight's TourProblem: You have an empty w
* h
chessboard, but for a single knight on some square. The knight must perform a sequence of legal moves that result in the knight visiting every square on the chessboard exactly once. Note that it is not a requirement that the tour be "closed"; that is, the knight need not end within a single move of its start position.
--instructions--
Write a function that takes w
and h
as parameters and returns the number of initial positions from where it is possible to achieve the task stated above.
--hints--
knightTour
should be a function.
assert(typeof knightTour == 'function');
knightTour(6, 6)
should return a number.
assert(typeof knightTour(6, 6) == 'number');
knightTour(6, 6)
should return 35
.
assert.equal(knightTour(6, 6), 35);
knightTour(5, 6)
should return 20
.
assert.equal(knightTour(5, 6), 20);
knightTour(4, 6)
should return 10
.
assert.equal(knightTour(4, 6), 10);
knightTour(7, 3)
should return 4
.
assert.equal(knightTour(7, 3), 4);
knightTour(8, 6)
should return 47
.
assert.equal(knightTour(8, 6), 47);
--seed--
--seed-contents--
function knightTour(w, h) {
}
--solutions--
function knightTour(w, h) {
var b,
cnt = 0;
var dx = [-2, -2, -1, 1, 2, 2, 1, -1];
var dy = [-1, 1, 2, 2, 1, -1, -2, -2];
function init_board() {
var i, j, k, x, y;
// * b is board; a is board with 2 rows padded at each side
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
b[i][j] = 255;
}
}
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
for (k = 0; k < 8; k++) {
(x = j + dx[k]), (y = i + dy[k]);
if (b[i][j] == 255) b[i][j] = 0;
if (x >= 0 && x < w && y >= 0 && y < h) b[i][j]++;
}
}
}
}
function walk_board(x, y) {
var i, nx, ny, least;
var steps = 0;
// printf(E"H"E"J"E"%d;%dH"E"32m[]"E"m", y + 1, 1 + 2 * x);
while (1) {
// * occupy cell
b[y][x] = 255;
// * reduce all neighbors' neighbor count
for (i = 0; i < 8; i++)
if (y + dy[i] >= 0 && x + dx[i] >= 0 && y + dy[i] < h && x + dx[i] < w)
b[y + dy[i]][x + dx[i]]--;
// find neighbor with lowest neighbor count
least = 255;
for (i = 0; i < 8; i++) {
if (y + dy[i] >= 0 && x + dx[i] >= 0 && y + dy[i] < h && x + dx[i] < w)
if (b[y + dy[i]][x + dx[i]] < least) {
nx = x + dx[i];
ny = y + dy[i];
least = b[ny][nx];
}
}
if (least > 7) {
return steps == w * h - 1;
}
steps++;
(x = nx), (y = ny);
}
}
function solve(x, y) {
b = new Array(h);
for (var i = 0; i < h; i++) b[i] = new Array(w);
init_board();
if (walk_board(x, y)) {
cnt++;
}
}
for (var i = 0; i < h; i++) {
for (var j = 0; j < w; j++) {
solve(j, i);
}
}
return cnt;
}