24-point game is a common intellectual game, which can be played with cards without jokers. The rule is to draw four random cards and manipulate the four numbers to get the result 24 using four arithmetic operations: addition, subtraction, multiplication and division. In card playing, J, Q, K correspond numbers 11, 12 and 13 respectively.

With esProc, we can conveniently program the game, and calculate the result with the four random numbers:

Next, let’s analyze this block of code in detail.

The four numbers for computations are given in A1. First, to calculate the 24 points we should try all possible permutations of the four cards. To do this, we list the permutations, including those with the repeated numbers, in A2 using a four-digit quaternary number. In B2, we only select those without repeated numbers. They are as follows:

Three arithmetic operators need to be inserted into four numbers during the computation. Each one is selected arbitrarily from addition, subtraction, multiplication and division. Execute loop in A3 on a three-digit quaternary number to list all possible combinations:

As different computational orders lead to different computed results, we can adjust the order by adding parentheses in different ways. Three operators mean the computation can be performed in three steps, and different ways of adding parentheses decide the order of the execution of the three steps. B3 selects from the results of A3 the combinations that contain all three elements 1, 2, 3. They represent all possible orders for execution, as shown below:

Since there could be repeated numbers among the four randomly selected cards, we’ll list all permutations of cards in A4 and remove those repeated ones in B4 in order to avoid redundant loops. For the numbers [8,3,8,3] specified in A1, B4 lists permutations as follows:

For each permutation, the code in line 5 and line 6 tries every combination of arithmetic operators in every computational order by loop. To do this, the code calls A8’s subroutine, which uses copied parameters to avoid affecting the subsequent computations.

When calling the subroutine in A8, the sequence of numbers, the sequence of operators, and the sequence of computational orders should be entered respectively into A8, B8 and C8; besides, expression for computation should be entered in D8. B9 loops through the sequence of computational orders to compute the results step by step. C9 gets the result of one step by calling the subroutine in A13. The subroutine, which is quite simple, computes the result of a four arithmetic operation based on two given numbers and the operator in between. D9 aims at the expression for computing one step, after which the original two numbers become one. Then modify the sequence expressions, the sequence of operators and the sequence of numbers in E9, C10 and D10. After solving one step, the original number of computational steps decreases by one, and then we need to modify the sequence of computational order in E10 again. In line 11, unless it is the last step, parentheses need to be added to the newly-generated expression to ensure an appropriate computational order.

When the loop in B9 is over, the subroutine in A8 completes its computation of expression for one type of permutation with one combination of operators. B18 evaluates whether the result is 24. Considering the computational error of double-precision number, the result will be rounded to three decimal places. If the result equals 24, the current combination can meet the requirement and the expression will be put in B1 through C12.

After looping through all combinations, if no expression is found in B1 by looking at A7, then the problem has no solution.

After all the computations, result can be found in B1, as shown below:

Instead of entering a fixed permutation of numbers into A1, we can also use a cellset parameter by modifying A1’s code into **=arg1**:

Set the cellset parameter before doing computation:

The result displayed in B1 after computation is as follows:

]]>For a given system of linear equations in *n* unknowns, there must be *n* equations to form the system. e.g.:

3x+4y+5z=26

5x+6y+10z=47

4x+8y+7z=41

Well, how do you solve this system of linear equations with *n* variables with esProc? First, the system of equations should be written in a standard form, and parameters are filled in a text file. Parameters in the same line are separated with Tab. As listed below:

How to solve systems of linear equations in *n* unknowns by programming? The method of elimination by addition and subtraction is widely used. See the following system of equations:

a_{11}x_{1}+a_{12}x_{2}+a_{13}x_{3}+…+a_{1n}x* _{n}*=a

a_{21}x_{1}+a_{22}x_{2}+a_{23}x_{3}+…+a_{2n}x* _{n}*=a

a_{31}x_{1}+a_{32}x_{2}+a_{33}x_{3}+…+a_{3n}x* _{n}*=a

……

a_{n}_{1}x_{1}+a_{n}_{2}x_{2}+a_{n}_{3}x_{3}+…+a* _{nn}x_{n}*=a

If a_{11 }is not equal to zero, we multiply each term of the first equation simultaneously by a_{21}/a_{11}, subtract the first equation from the second one, then the coefficient of x_{1 }in the second equation becomes zero. If a_{11} equals zero, we need to find an equation in which the coefficient of x_{1} is not zero, and make it the first. In this way, we can eliminate all coefficients of x_{1} in the equations after the first one. See below:

a_{11}x_{1}+a_{12}x_{2}+a_{13}x_{3}+…+a_{1n}x* _{n}*=a

0+b_{22}x_{2}+b_{23}x_{3}+…+b_{2n}x* _{n}*=b

0+b_{32}x_{2}+b_{33}x_{3}+…+b_{3n}x* _{n}*=b

……

0+b_{n}_{2}x_{2}+b_{n}_{3}x_{3}+…+b* _{nn}x_{n}*=b

Now let’s look at the case of b_{22}. In the same method, we continue to eliminate coefficients of x_{2 }in all equations after the second one… We do this continuously until the coefficient of x_{n}_{-1} in the *n*th equation is eliminated. At this point, the system of equations will be like the following:

a_{11}x_{1}+a_{12}x_{2}+a_{13}x_{3}+…+a_{1n}x* _{n}*=a

0+b_{22}x_{2}+b_{23}x_{3}+…+b_{2n}x* _{n}*=b

0+0+c_{33}x_{3}+…+c_{3n}x* _{n}*=c

……

0+0+0+…+m* _{nn}x_{n}*=m

And we can solve it step by step from the *n*th equation:

x* _{n}*=m

_{……}

x_{3}=(c_{30}-…-c_{3n}x* _{n}*)/c

x_{2}=(c_{30}-b_{23}x_{3}-…-b_{2n}x* _{n}*)/b

x_{1}=(c_{30}-a_{12}x_{2}-a_{13}x_{3}-…-a_{1n}x* _{n}*)/a

If, during the calculation, zero appears in parameters like a_{11}，b_{22}，c_{33},the system of equations has no solution or infinitely many solutions.

The following shows how to solve a system of linear equations in *n* unknowns with esProc:

A | B | C | D | |

1 | =file(“EquInput.txt”) | =A1.import() | =B1.len() | >result=[0]*C1 |

2 | =B1.((C1+1).(B1.~.field(#))) | |||

3 | for C1-1 | =0 | ||

4 | for A3,C1 | if A2(B4)(A3)!=0 | >B3=B4 | |

5 | break | |||

6 | if B3==0 || A3==C1 | next | ||

7 | =A2(B3) | >A2(B3)=A2(A3) | >A2(A3)=B7 | |

8 | for A3+1,C1 | if A2(B8)(A3)==0 | next | |

9 | for C1+1,A3 | >A2(B8)(C9)-=B7(C9)*A2(B8)(A3)/B7(A3) | ||

10 | for C1,1 | =C1.sum(result(#)*A2(A10)(#)) | ||

11 | if A2(A10)(A10)!=0 | >result(A10)=round((A2(A10)(C1+1)-B10)/A2(A10)(A10),4) | ||

12 | else | >result=”Error” | break | |

13 | =result |

In B1, data is read from the text file; Parameters of the system of equations are transformed into sequence groups in A2:

C1 seeks the number of equations in the system of equations, then the result gets looping execution in A3, and coefficients of x* _{n }*will be gradually eliminated with the method of elimination by addition and subtraction. During looping execution in B4, we look for the first equation in which the coefficient of x

Having done the elimination of every step, we can start to work out solution gradually from the last equation in A10, during which a sequence called result will be used to store solutions. If there is no solution or infinite many solutions, return Error. Considering that there could be errors with double-precision number during computation, the solutions will be kept to four decimal places.

Result can be viewed in A13 after all computations:

If new system of equations is required to be solved:

7x_{1}+2x_{2}+9x_{3}-x_{4}=0

2x_{1}+9x_{2}-x_{4}=0

9x_{1}+11x_{3}-x_{4}=0

x_{1}+x_{2}+x_{3} =1

We only need to modify the EquInput.txt file:

With the same program, we compute and read result in A13.

In addition, list of parameters is unnecessary to be imported from a file. Instead, they can be written directly in esProc. The computing progress is similar to that we’ve explained.

]]>Among lots of chess puzzles, the problem of the eight queens is the most well-known example. Eight queens must be placed on a 8×8 chessboard so that no queen attacks any others. Well, how many solutions are there?

A queen attacks any other queen that sits on the same row, column or diagonal. Thus a solution requires that no two queens share the same row, column or diagonal.

Since there is only one queen in each row, a sequence, the length of which is 8, can be employed to set in turn the **sequence number of the column** on which a queen on each row sits. For a row on which no queen has been placed, the column number is zero; every time when we put a new queen on the board, if the sequence number of the column is not one of the existing members of the sequence, then no other queen sits on the same column.

At the same time, we need to make sure there is no other queen on a diagonal when we place a new queen on it. If the queen sits on row *m* of column *k*, there are two squares at most on row m+n that share the same diagonal with it; and the horizontal distance between either of the squares and the queen equals the vertical distance between them. This means there are two squares (m+n,k+n) and (m+n,k-n) at most share the same diagonal with it.

So, we will know the number of solutions by looking at all squares of a row on which a queen is placed.

esProc does this by performing loop operation, as shown below:

A | B | C | D | |

1 | =[0]*8 | >i=1 | ||

2 | for i>0 | >A1(i)=A1(i)+1 | ||

3 | if A1(i)==9 | >A1(i)=0,i=i-1 | next | |

4 | if i==1 | >i=2 | next | |

5 | =A1(i) | =A1.to(i-1) | ||

6 | if C5.pos(B5)>0 | next | ||

7 | else if C5.pselect(i-#==abs(B5-~))>0 | next | ||

8 | >i=i+1 | |||

9 | if i==9 | >C1=C1|A1.conj@s() | >A1(8)=0,i=7 | |

10 | =C1.len() |

i is used during the computation to represent the sequence number of the current row where a queen is placed. The code in the 2nd line executes loops, in which after each loop the queen on the current row will move to the next column. In this way, every square of the current row is traversed. About the code in the 3rd line: When the queen moves to the 9th column, the traversal of all squares in the current row has completed; at this point, reset the sequence number of column for traversing through the row to zero and subtract 1 from i and begin loop on the next row. In particular, when all the squares of the first row are looped through, the entire traversal is completed. Now i is reset to zero and the loop exits. About the code in the 4th line: when moving the queen along the first row, there is no need to judge if a square is eligible for holding a queen; just place the second queen. The code in the 6th line judges if there is any column shared by the settled queens, and the code in the 7th line judges whether there is any diagonal shared by them. If results of both judgments are true, we can go on to place the queen on the next row. When all the eight queens are settled, store their current places with the code in the 9th line.

The computed result in A10 is:

We can see detailed result in C1:

We can also solve the problem by recursively calling a subroutine:

A | B | C | D | E | |

1 | =[0]*8 | >func(A2,A1,1) | =C1.len() | ||

2 | func | =A2.to(B2-1) | |||

3 | for 8 | if C2.pos(B3)>0 | next | ||

4 | if B2==1 | >A2(B2)=B3 | |||

5 | >func(A2,A2,B2+1) | next | |||

6 | for C2 | if B2-#C6==abs(C6-B3) | next B3 | ||

7 | >A2(B2)=B3 | ||||

8 | if B2==8 | >C1=C1|A2.conj@s() | |||

9 | else | >func(A2,A2,B2+1) |

In A2’s subroutine, a queen is placed on a row. B3 loops through every possible column. C3 judges if there is already a queen on the current column. The 6^{th} line judges if a queen already exists on the diagonals, and if it exists, try next column. If a certain column is eligible, then call the subroutine recursively and move on to the next row to place the queen. Store places of the eight queens in C1 after they are all settled. This approach produces the same result but easier code.