Javascript solves Level 3 Magic Square (jiugongge) and level 3 Magic Square

Source: Internet
Author: User

Javascript solves Level 3 Magic Square (jiugongge) and level 3 Magic Square

Puzzle: Level 3 magic. Try to use level 1 ~ 9 fill in the nine different integers in a 3 × 3 table, so that the sum of numbers on each row, column, and each diagonal line is the same.

Policy: search by exhaustive means. List all integer filling schemes and filter them.

The highlight is the design of the recursive function getPermutation. At last, this article provides several non-recursive algorithms.

// Recursive algorithm, clever, but overcharged Resource function getPermutation (arr) {if (arr. length = 1) {return [arr];} var permutation = []; for (var I = 0; I <arr. length; I ++) {var firstEle = arr [I]; // obtain the first element var arrClone = arr. slice (0); // copy the array arrClone. splice (I, 1); // Delete the first element and reduce the array scale var childPermutation = getPermutation (arrClone); // recursive for (var j = 0; j <childPermutation. length; j ++) {childPermutation [j]. unshift (firstEle );/ /Insert the retrieved element back} permutation = permutation. concat (childPermutation);} return permutation;} function validateCandidate (candidate) {var sum = candidate [0] + candidate [1] + candidate [2]; for (var I = 0; I <3; I ++) {if (! (SumOfLine (candidate, I) = sum & sumOfColumn (candidate, I) = sum) {return false ;}} if (sumOfDiagonal (candidate, true) = sum & sumOfDiagonal (candidate, false) = sum) {return true;} return false;} function sumOfLine (candidate, line) {return candidate [line * 3] + candidate [line * 3 + 1] + candidate [line * 3 + 2];} function sumOfColumn (candidate, col) {return candidate [col] + candidate [col + 3] + candidate [col + 6];} function sumOfDiagonal (candidate, isForwardSlash) {return isForwardSlash? Candidate [2] + candidate [4] + candidate [6]: candidate [0] + candidate [4] + candidate [8];} var permutation = getPermutation ([1, 2, 3, 4, 5, 6, 7, 8, 9]); var candidate; for (var I = 0; I <permutation. length; I ++) {candidate = permutation [I]; if (validateCandidate (candidate) {break;} else {candidate = null;} if (candidate) {console. log (candidate);} else {console. log ('no valid result found ');}/ /Modulo (non-recursive) Full permutation algorithm/* specific example of an algorithm: * obtain four elements ["a", "B", "c ", "d"] in full order, a total of 4 cycles! = 24 times. It can start from any integer index> = 0 and accumulate 1 at a time until the cycle ends after index + 23; * assume that the index is 13 (or 13 + 24, 13 + 224,13 + 3*24 ...), Because there are four elements in total, so the iteration is four times, the resulting sorting process is: * 1st iterations, 13/1, operator = 13, remainder = 0, therefore, if 1st elements are inserted at 0th locations (I .e., the subscript is 0), ["a"]; * 2nd iterations, 13/2, operator = 6, remainder = 1, therefore, if 2nd elements are inserted at 1st locations (I .e., the subscript is 1), ["a", "B"]; * 3rd iterations, 6/3, operator = 2, the remainder is 0. Therefore, 3rd elements are inserted at 0th locations (I .e., the subscript is 0). ["c", "a", "B"]; * 4th iterations, 2/4, quotient = 0, remainder = 2, so 4th elements are inserted into 2nd positions (I .e., subscript is 2), get ["c", "a", "d ", "B"]; */function perm (arr) {var result = new Array (arr. length); var fac = 1; for (var I = 2; I <= arr. length; I ++) // calculates the number of fac * = I based on the array length. for (var Index = 0; index <fac; index ++) {// each index corresponds to an array var t = index; for (I = 1; I <= arr. length; I ++) {// determine the position of each number. var w = t % I; for (var j = I-1; j> w; j --) // shift, leave space for result [w] result [j] = result [j-1]; result [w] = arr [I-1]; t = Math. floor (t/I);} if (validateCandidate (result) {console. log (result); break ;}} perm ([1, 2, 3, 4, 5, 6, 7, 8, 9]); // clever backtracking algorithm, non-recursive solution to fully arrange function seek (index, n ){ Var flag = false, m = n; // flag is the marker for finding the position arrangement. m stores the position being searched, and index [n] is the element (location encoding) do {index [n] ++; // set the current position element if (index [n] = index. length) // available index [n --] =-1; // reset the current position and roll back to the previous position else if (! (Function () {for (var I = 0; I <n; I ++) // determine whether the current position is set in conflict with the previous position if (index [I] = index [n]) return true; // conflict, directly return to the loop and re-set the element value return false; // no conflict, check whether the current position is the end of the queue, yes, find an arrangement; no, the current position is moved back })()) // if (m = n) is not selected for this position. // The current position is searched. flag = true; else n ++; // the current and previous position elements are arranged, position move back} while (! Flag & n> = 0) return flag;} function perm (arr) {var index = new Array (arr. length); for (var I = 0; I <index. length; I ++) index [I] =-1; for (I = 0; I <index. length-1; I ++) seek (index, I); // initialize to 1, 2, 3 ,..., -1: The last element is-1. Note that it is small to large. If the element is not a number, it can be understood as its position subscript while (seek (index, index. length-1) {var temp = []; for (I = 0; I <index. length; I ++) temp. push (arr [index [I]); if (validateCandidate (temp) {console. log (temp); break ;}} perm ([1, 2, 3, 4, 5, 6, 7, 8, 9]);

/*
Full Permutation (non-recursive order) Algorithm
1. Create a location array, that is, arrange the positions, and convert them to the arrangement of elements;
2. Perform full sorting according to the following algorithms:
Set P to 1 ~ A full arrangement of n (Location Number): p = p1, p2... pn = p1, p2... PJ-1, pj, pj + 1... pk-1, pk, pk + 1... pn
(1) from the end of the arrangement, find the first index j, which is smaller than the number on the right (j starts from the header ), that is, j = max {I | pi <pi + 1}
(2) In the position number on the Right of pj, find all the INDEX k with the smallest position number greater than pj, that is, k = max {I | pi> pj}
The position number on the Right of pj increases progressively from right to left, so k is the largest index among all the position numbers greater than pj.
(3) Switch pj and pk
(4) then pj + 1... pk-1, pk, pk + 1... pn flipped to get the P' = p1, p2... PJ-1, pj, pn... pk + 1, pk, pk-1... pj + 1
(5) P' is the next arrangement of p.

For example:
24310 is the position number 0 ~ 4. The following steps are taken to find the next arrangement:
(1) from the right to the left, find the first number that is smaller than the number on the right. 2;
(2) Find the smallest 3 of the two digits after the number;
(3) Exchange 2 and 3 for 34210;
(4) flip all the numbers behind the original 2 (current 3), that is, flip 4210 to 30124;
(5) The next order of 24310 is 30124.
*/

Function swap (arr, I, j) {var t = arr [I]; arr [I] = arr [j]; arr [j] = t ;} function sort (index) {for (var j = index. length-2; j> = 0 & index [j]> index [j + 1]; j --); // This loop starts from the end of the position array, locate the position on the left that is less than the right, that is, j if (j <0) return false; // all rows have been completed for (var k = index. length-1; index [k] <index [j]; k --); // This loop starts from the end of the position array and finds the smallest position greater than the j position, that is, k swap (index, j, k); for (j = j + 1, k = index. length-1; j <k; j ++, k --) swap (index, j, k ); // return true for all positions from j + 1 to the end of this loop;} function perm (arr) {var index = new Array (arr. length); for (var I = 0; I <index. length; I ++) index [I] = I; do {var temp = []; for (I = 0; I <index. length; I ++) temp. push (arr [index [I]); if (validateCandidate (temp) {console. log (temp); break;} while (sort (index);} perm ([1, 2, 3, 4, 5, 6, 7, 8, 9]);

The above is all the content of this article. I hope you will like it.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.