(04-03-2015 08:43 PM)PANAMATIK Wrote: [ -> ]Perhaps you are aware, perhaps not, that many other members or nonmembers are reading this thread with great pleasure, seeing your efforts and results, without being able to participate in these kind of mathematics games, but admiring it. I'm one of these quiet readers and want to congratulate any of you in advance for finding all the n-th order solution eggs.
Happy Easter!
Bernhard
Thanks for the encouragement. You shall be rewarded with the full source code:
For proper code optimization, this is the variable numbering (quite strange for humans, but optimized for the machine:
Code:
A B C
L R M D
K Q S N E
J P O F
I H G
A trough L are the outer ring, where we can write the first 6 equations with only 3 letters each, and completely decoupled from the rest. This allows to solve for the first 6 variables out of seven. As explained in my previous post, the code walks the perimeter setting a number for A, then trying all values of B knowing A+B>=19, and computing C per the corresponding equation C=38-(A+B).
This is done by this code:
Code:
@@ AUXILIARY ROUTINE 'TAKEN' CHECKS IF THE NUMBER ON LEVEL 1
@@ WAS ALREADY PRESENT IN THE STACK, RETURNS 1=WAS TAKEN, 0=NOT REPEATED
<< DEPTH IF 1 <= THEN 0 ELSE
0 -> RESULT <<
DEPTH 1 + 3 SWAP FOR K DUP K PICK
IF == THEN 1 'RESULT' STO 1000 'K' STO END NEXT
RESULT >>
END
>> 'TAKEN' STO
@@ ROUTINE DOLOOP DOES THE RECURSION FOR THE OUTER RING
@@ EXPECTS THE FIRST VALUE TO BE ON THE STACK ALREADY
@@ IT LEAVES ONLY THAT ORIGINAL VALUE ON THE STACK UPON EXIT
@@ TRIES ALL POSSIBLE COMBINATIONS OF THE OUTER RING
<< DEPTH IF 11 == THEN
@@ SPECIAL CASE TO "CLOSE" THE RING ONCE WE HAVE ALL VARIABLES
11 PICK OVER + 38 SWAP -
IF TAKEN NOT OVER 1 >= AND OVER 19 <= AND THEN
@@ IF THE RING "CLOSED", THEN DO THE INNER RING CHECK...
CHKINNER
END DROP
ELSE
@@ REGULAR CASE, TRY ALL VALUES IN A LOOP FOR THE NEXT NUMBER
19 OVER - DUP 1 < + 19 SWAP FOR K K
IF TAKEN THEN DROP ELSE
2 DUPN + 38 SWAP -
IF TAKEN NOT THEN DOLOOP END
DROP DROP
END
-1 STEP
END
>> 'DOLOOP' STO
M is the 7th independent variable. Once the outer ring is known, trying all possible values for M allows to calculate all letters N through R in the "inner ring" by using the 4-term equations.
N=38-(B+M+F)
O=38-(D+N+H)
...
The inner ring code expects to find already on the stack the 12 variables A through L with L on level 1.
The inner ring is solved by this code:
Code:
@@ ROUTINE CHKINNER, COMPUTES THE LAST REMAINING INDEP. VARIABLE
@TRY ALL NUMBERS FROM 1 THROUGH 19 IN A LOOP
<< 1 19 FOR K
K IF TAKEN THEN DROP ELSE
@@ IF THE NUMBER WAS VALID, THEN SOLVE FOR N THROUGH R
@@ USING THE EQUATIONS WITH 4-TERMS
IF 1 -> INNERCHECK << 1 5 FOR J 13 J 2 * - DUP
IF 1 < THEN 12 + END J + PICK
10 J 2 * - DUP
IF 1 < THEN 12 + END J + PICK
+ OVER + 38 SWAP -
IF TAKEN OVER 1 < OR OVER 19 > OR THEN
J DROPN 0 'INNERCHECK' STO 1000 'J' STO
END
NEXT
INNERCHECK >>
THEN
@@ INNER RING CHECKS OUT, NOW CHECK THE
@@ CENTER VALUE BEFORE WE CLAIM TO HAVE A SOLUTION
IF CHKCENTER THEN
@@ WE HAVE A SOLUTION, ADD IT TO A LIST CALLED 'SOLUTIONS'
19 DUPN 19 ->LIST 1 ->LIST
SOLUTIONS SWAP + 'SOLUTIONS' STO
7 DROPN
ELSE 6 DROPN
END
ELSE DROP
END
END
NEXT
>> 'CHKINNER' STO
Finally, we need to do the proper checks with the center value (last position, S).
All we have to do is find the only number that was not taken in the stack and check all 3 equations with 5-terms.
This is done here:
Code:
@@ ROUTINE CHKCENTER CHECKS IF THE CENTER VALUE IS CORRECT
@@ USING THE 5-TERM EQUATIONS
<< 1 19 FOR K
K IF TAKEN NOT THEN 1000 'K' STO ELSE DROP END
NEXT
19 PICK 3 PICK + OVER + 6 PICK + 14 PICK + IF 38 == THEN
17 PICK 8 PICK + OVER + 5 PICK + 12 PICK + IF 38 == THEN
9 PICK 4 PICK + OVER + 7 PICK + 16 PICK + IF 38 == THEN
1
ELSE DROP 0 END
ELSE DROP 0 END
ELSE DROP 0 END
>> 'CHKCENTER' STO
And to wrap it all up, the code above needs a couple of things to run properly:
- A variable named 'SOLUTIONS' initialized to an empty list
- A clear stack
- A loop to try all 19 initial values
This is done here:
Code:
@@ ROUTINE RUNIT DOES THE COMPLETE TEST
<< { } 'SOLUTIONS' STO
CLEAR
1 19 FOR I I DOLOOP DROP NEXT
SOLUTIONS LIST->
>> 'RUNIT' STO
For the short of patience, partial tests can be ran, if you put a partial list of numbers (must be a valid partial solution, of course), and run the DOLOOP test to see if any solutions are found.
Just make sure 'SOLUTIONS' contains an empty list and that there's nothing else in the stack but your partial solution.
The partial solution has to contain 1, 3, 5... elements. In other words, think of the corners as the independent variables, then to give 2 independent variables you must also provide the intermediate value between them (A, B and C).
This is tested and finds all 12 solutions, but of course I tested it on a PC with newRPL, don't have the patience to wait 19 hours, but if somebody does, please measure time and report here.
Happy coding.
PS: Still not a one-line RPL solution... but faster than my first try at 97 days!
EDIT:
Forgot to mention, if you don't wait to wait 19 hours, and don't care about the different rotations, you can get a nice solution by doing:
Code:
{ } 'SOLUTIONS' STO 3 DOLOOP
This will leave SOLUTIONS with all solutions that have a 3 in the first variable: exactly 2 solutions, one mirror of the other, and only for about
1 hr of your time.