Javascript solution third-level magic

Source: Internet
Author: User

Javascript solution third-level magic

Javascript solution third-level magic

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.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

// Recursive algorithms, clever but resource-consuming

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 to reduce the array size

Var childPermutation = getPermutation (arrClone); // Recursion

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) permutation algorithm

 

/*

Example of an algorithm:

* Find the full arrangement of the four elements ["a", "B", "c", "d"], repeating 4 in total! = 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, the process of this arrangement is obtained after four iterations:

* For 1st iterations, 13/1, quotient = 13, and remainder = 0, 1st elements are inserted at 0th positions (I .e., the subscript is 0). ["a"] is obtained.

* For 2nd iterations, 13/2, quotient = 6, and remainder = 1, 2nd elements are inserted at 1st positions (I .e., the subscript is 1). ["", "B"];

* 3rd iterations, 6/3, quotient = 2, and remainder = 0. Therefore, 3rd elements are inserted at 0th positions (I .e., the subscript is 0). ["c", "", "B"];

* For 4th iterations, 2/4, quotient = 0, and remainder = 2, 4th elements are inserted at 2nd positions (I .e., subscript is 2). ["c", "", "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 arrays based on the array length.

Fac * = I;

For (var index = 0; index <fac; index ++) {// each index corresponds to an arrangement

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 to 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 for full Arrangement

 

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] ++; // sets the current position Element

If (index [n] = index. length) // No location is 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 in conflict with the previous position

If (index [I] = index [n]) return true; // conflict, directly return to the loop to reset the element value

Return false; // no conflict. Check whether the current position is the end of the queue. If yes, locate an arrangement. If no, move the current position back.

}) () // This location is not selected

If (m = n) // The current position is searched

Flag = true;

Else

N ++; // the current and previous position elements have been arranged, and the position is moved 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.

*/

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

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 cycle starts from the end of the position array and finds the position with the first left less than the right, that is, j

If (j <0) return false; // All sorted

For (var k = index. length-1; index [k] <index [j]; k --)

; // This cycle 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); // in this loop, flip all positions from j + 1 to the end

Return true;

}

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.