88 lines
2.3 KiB
JavaScript
88 lines
2.3 KiB
JavaScript
// Add event listener to button to solve when clicked.
|
|
window.onload = function() {
|
|
document.getElementById('go').addEventListener('click', solve);
|
|
}
|
|
|
|
/*
|
|
* The layout of the game board is as follows:
|
|
*
|
|
* 0
|
|
* 1 2 3 4
|
|
* 5 6
|
|
* 7 8 9 10
|
|
* 11
|
|
*
|
|
* The puzzle is to find an arrangement of numbers
|
|
* so that every line adds up to 26.
|
|
*/
|
|
|
|
var solutions = [];
|
|
|
|
function solve() {
|
|
// Call recursive cyclePlace function on an empty starting arragement ([]).
|
|
cyclePlace(0, []);
|
|
|
|
console.log(solutions.length + ' solutions found');
|
|
}
|
|
|
|
// Function that accepts an incomplete arrangement and calls itself 12 times for
|
|
// each possible value of the next part of the arrangement added on to the current one.
|
|
// Each one of these calls then calls 12 more for the next arrangement and so on, totalling
|
|
// 12^n calls needed, which is reduced by early checks. A call at depth 11 performs a test
|
|
// on the given complete arrangement and adds it to the list of solutions if correct.
|
|
function cyclePlace(n, prev) {
|
|
// Stop early if first checkable line is invalid. This drastically improves speed.
|
|
if(n == 5) {
|
|
if(prev[1] + prev[2] + prev[3] + prev[4] != 26) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Again, but for second checkable line.
|
|
if(n == 8) {
|
|
if(prev[0] + prev[2] + prev[5] + prev[7] != 26) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// More checks could be added here but the program is fast enough as-is.
|
|
|
|
// Perform 12 deeper calls for each of the possible permutations of the next arrangement.
|
|
for(var i = 1; i <= 12; i++) {
|
|
if(prev.indexOf(i) == -1) {
|
|
// If deepest call.
|
|
if(n == 11) {
|
|
if(test(prev.concat(i))) {
|
|
// Add arrangement to solutions if correct.
|
|
solutions.push(prev.concat(i));
|
|
console.info('SOLUTION: ' + prev.concat(i));
|
|
};
|
|
} else {
|
|
cyclePlace(n + 1, prev.concat(i));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Test is given arrangement is correct.
|
|
function test(order) {
|
|
// The indices of the numbers that make up each line.
|
|
var lines = [
|
|
[0, 2, 5, 7],
|
|
[1, 5, 8, 11],
|
|
[7, 8, 9, 10],
|
|
[11, 9, 6, 4],
|
|
[10, 6, 3, 0],
|
|
[4, 3, 2, 1]
|
|
];
|
|
|
|
// Cycle through each line and ensure its sum is 26.
|
|
for(var i = 0; i < 6; i++) {
|
|
var line = lines[i];
|
|
if(order[line[0]] + order[line[1]] + order[line[2]] + order[line[3]] != 26) return false;
|
|
}
|
|
|
|
// Return true if no incorrect line caused a return false first.
|
|
return true;
|
|
}
|
|
|