Yesterday in science on the internet to learn such a news, "Vietnamese primary math puzzles Dr", is known to be the title from the Vietnamese Paul Elementary school three years, but reported that the problem baffled the doctor down to the parents, it is too exaggerated.
Title Description
Students need to fill in the form from top to bottom, from left to right in the order of 1~9 numbers, can be repeated, and the first multiplication after adding minus (the colon in the picture represents division) algorithm, complete the whole calculation.
Solving Methods
Obviously, this is not a problem for us programmers, as long as the students in the C language (our school has learned C, even the liberal arts major) can basically use the Kokonoe for loop to solve the problem, the following I use C and MATLAB to achieve, and the MATLAB algorithm has been improved.
C language implementation:
#include <stdio.h>#include <time.h>voidMain () {clock_t start, finish;//For timekeeping DoubleDuration start = Clock ();Doubleresult=0;//Store calculation results to see if it is equal to 66 intindex=0;intnum=0; for(intA=1;a<Ten; a++) for(intb=1;b<Ten; b++) for(intC=1;c<Ten; C + +) for(intD=1;d <Ten;d + +) for(intE=1;e<Ten; e++) for(intf=1;f<Ten; f++) for(intg=1;g<Ten; g++) for(intH=1;h<Ten; h++) for(intI=1;i<Ten; i++) {result=a+ -*b/float(c) +d+ A*e-f- One+g*h/float(i)-Ten;if(result== the) {//The results of the solution can be printed herenum=num+1; }} finish = Clock (); Duration = (Double) (Finish-start)/clocks_per_sec;printf("A total of%d results \%f seconds \ n", num,duration);}
The results are shown below:
MATLAB Implementation
- The most straightforward method : it takes 4911.131591 seconds.
Clear all;ans=[]; tic forA=1:9 forb=1:9 forC=1:9 forD=1:9 forE=1:9 forf=1:9 forg=1:9 forH=1:9 for I=1:9result=a+ -*b/c+d+ A*e-f- One+g*h/I-Ten;ifresult== the; Answer=[a b c D e F g h i];ans=[Ans;answer];End End End End End End End End EndEndToc
In the above algorithm, the operation of storing the result answer is very time-consuming and we can find a way to optimize it. I then commented out the process of storing the results (removing the IF statement block), which took 16.814298 seconds and reduced the time from one hours to more than 10 seconds. But even if the results are not stored, it takes 16.814298 seconds, which is still a gap with the C language (and no storage results) for 4 seconds! Let me tell you how to improve the algorithm.
improved MATLAB implementation
In the previous article, "MATLAB high-efficiency programming skills," it was mentioned to avoid multiple loops, multi-use vectorization functions . So I decided to use matrices instead of this 9-heavy loop.
Let's start with a simple example : Suppose there are 2 one-dimensional arrays, a-B, whose elements are 1:9, it is obvious that the result of arithmetic (which we assume is multiplied) between any of the 2 arrays is 9*9, which can be represented by a 9*9 two-dimensional array; Assuming that there are 3 one-dimensional array a,b,c, whose elements are all 1:9, we are going to calculate the result of arithmetic between any of these three arrays, so that there is a total of 9*9*9 items, exactly one 9*9*9 three-dimensional array storage; and so on, we can get 9 one-dimensional array elements arithmetic can be used 9 A 9-D array representation of the *9*9*9*9*9*9*9*9*9.
However, in MATLAB, * can only be used for the multiplication of two-dimensional arrays, fortunately we can use the Bsxfun function to calculate the different dimension array. Here is an example of how bsxfun is used:
Clear Alla=ones(9,1);% Note a one-dimensional column vector is equivalent to a two-dimensional vector of size 9*1b=ones(1,9); c=ones(1,1,9); A (1:9)=1:9b1,1:9)=1:9C1,1,1:9)=1:9; temp1=Bsxfun(@times, A, b)% multiplication A*b Temp1 is a two-dimensional array of 9*9Temp2=Bsxfun(@plus, A, b)% addition A+btemp3=Bsxfun(@times, Temp1,c)% multiplication A*b*c 9*9*9 three-dimensional array
By running the above results, you can find thatBsxfun completes the result of a arithmetic of 22 between any element, and does not require the dimension to be equal。 Of course, the operation principle and function of Bsxfun can be viewed in MATLAB's own documentation. Our algorithm only needs the above function to be able,In the program, I calculated the formula a+13*b/c+d+12*e-f-11+g*h/i-10 as < Span class= "Mrow" id= "mathjax-span-11" > a , b ? i All of the combined values, stored in Abcdefghi, and finally the index of the index that contains the element with the value 66 in the array Abcdefghi, which is the solution to the problem。 The specific MATLAB program is implemented as follows:
Clear Alltic% makes a,b,c,d,e,f,g,h,i vectors for 1,2,3,4,5,6,7,8,9 dimensions, respectivelyA=ones(9,1);% Note a one-dimensional column vector is equivalent to a two-dimensional vector of size 9*1b=ones(1,9); c=ones(1,1,9);d =ones(1,1,1,9); e=ones(1,1,1,1,9); f=ones(1,1,1,1,1,9); g=ones(1,1,1,1,1,1,9); h=ones(1,1,1,1,1,1,1,9);I=ones(1,1,1,1,1,1,1,1,9); A (1:9)=1:9; B (1,1:9)=1:9=cn1,1,1:9)=1:9;d(1,1,1,1:9)=1:9E1,1,1,1,1:9)=1:9; F (1,1,1,1,1,1:9)=1:9; G (1,1,1,1,1,1,1:9)=1:9; H (1,1,1,1,1,1,1,1:9)=1:9;I(1,1,1,1,1,1,1,1,1:9)=1:9;% mainly use Bsxfun function to realize the arithmetic of different dimension functions%a+13*b/c+d+12*e-f-11+g*h/i-10=66b=Bsxfun(@times, B, -); bc=Bsxfun(@rdivide, b,c); gh=Bsxfun(@times, g,h); ghi=Bsxfun(@rdivide, GH,I); abc=Bsxfun(@plus, A,BC); abcd=Bsxfun(@plus, abc,d); e=Bsxfun(@times, E, A); abcde=Bsxfun(@plus, abcd,e); abcdef=Bsxfun(@minus, abcde,f); abcdef=Bsxfun(@minus, ABCdef, One); abcdefghi=Bsxfun(@plus, Abcdef,ghi); abcdefghi=Bsxfun(@minus, Abcdefghi,Ten); toccounter=Find(abcdefghi== the);% find Subscript index[L1,L2,L3,L4,L5,L6,L7,L8,L9]=ind2sub(size(Abcdefghi), counter (1))% This is a possible solution.
running results such as:
As you can see, this method takes 4.183608 seconds, and I only show the first 10 results in the figure, and only the value of the Abcdefghi that corresponds to the first result 45 is calculated, and its value is in the variable space:
It can be seen that thecounter size is 442232, that is, a total of 442,232 solutions, of which counter (1) =45, the corresponding solution is abcdefghi=9 5 1 1 1 1 1 1 1 1 1.
Note : This program, which is running on a lab workstation (memory 128g), will not run successfully due to insufficient memory in the small computer.
Results Analysis
When programming with MATLAB, avoid using multiple loops and try to think of the problem as a matrix. By the above program time-consuming comparison can be seen, with C language implementation and my improved algorithm time is about 4 seconds, and the C language implementation is in the case of no storage solution, if the same to store the results (storage results can be used in different data structures: Linked lists, queues, etc.), who is more time-consuming and perhaps! The two MATLAB implementations mentioned in this article know that the first method takes up little memory and can run on a normal computer, but it takes a long time, but the algorithm we improve is short, but it occupies a large amount of memory and cannot run on a machine with small memory. This is called the time to change space, space change time!
Original: http://blog.csdn.net/tengweitw/article/details/45014771
Nineheadedbird
"Algorithmic Programming" PhD in Math problems in primary schools