Author 
Topic: Magic Squares 4x4 Solver (Read 508 times) 

Rod
Administrator
member is offline
Graphics = Goosebumps!
Gender:
Posts: 3184


Re: Magic Squares 4x4 Solver
« Reply #1 on: Sep 12^{th}, 2017, 08:37am » 

Nice, your next challenge is to draw a molecular model using Just BASIC's easy to use drawing commands! Oh, and drop the line numbers, gives your age away!
Edit to add: Tried to see how we could stop jumping out of for next loops. This is a no no in Just BASIC. You are supposed to use exit for if you terminate a loop early. That said the code runs.

« Last Edit: Sep 12^{th}, 2017, 09:06am by Rod » 
Logged




rtr
Member in Training
member is offline
Posts: 42


Re: Magic Squares 4x4 Solver
« Reply #2 on: Sep 12^{th}, 2017, 1:11pm » 

on Sep 12^{th}, 2017, 08:37am, Rod wrote:Tried to see how we could stop jumping out of for next loops. This is a no no in Just BASIC. 

Are you sure there are any? On a (very) quick scan of the program, all the GOTOs seem to be jumping to the matching NEXT statement, and therefore are not jumping out of the loop and should be perfectly safe.
That said, obviously GOTO is not considered 'pukka' these days, from a structured programming viewpoint, but that's a style issue rather than anything that could cause the program to fail.
Richard.


Logged




bplus
Senior Member
member is offline
Gender:
Posts: 1290


Re: Magic Squares 4x4 Solver
« Reply #3 on: Sep 12^{th}, 2017, 6:38pm » 

Speaking of scan, this is 'pukka' for it. Is number 678 correct?


Logged

B+



Rod
Administrator
member is offline
Graphics = Goosebumps!
Gender:
Posts: 3184


Re: Magic Squares 4x4 Solver
« Reply #4 on: Sep 13^{th}, 2017, 01:55am » 

Speaking of scan, yes it could do with a scan to allow breaking out early. Also jumping to next is fine.


Logged




bplus
Senior Member
member is offline
Gender:
Posts: 1290


Re: Magic Squares 4x4 Solver
« Reply #5 on: Sep 13^{th}, 2017, 7:21pm » 

I ran some checks on the numbers the program was writing like confirming the numbers all added up and that duplicate data was not displayed. All looks good and now you can study Square #678.
This code writes the Magic Square Data to disk file: Code:
' ****** MAGIC SQUARES 4x4 SOLVER ****************
' * *
' * FREEWARE by prof. Daniele Mazza *
' * mazzad50@gmail.com www.molecularmodels.eu *
' * *
' **************************************************
' A magic square is a n times n square grid (where n is the number of cells on each side) filled with positive
' integers in the range 1 to n^2 such that each cell contains a different integer and the sum of the integers in each row
' column and diagonal is equal. This sum is called the magic constant or magic sum of the magic square.
' Here we generate the 880 magic squares of order 4 (magic sum is 34) discarding those obtained by reflections and rotations.
GLOBAL q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, q13, q14, q15, q16
open "Magic Square 4 data.txt" for output as #1
mainwin 64 24
locate 10,4: print "+++++" '++
locate 10,5: print "    " ' q1  q2  q3  q4 
locate 10,6: print "+++++" '++
locate 10,7: print "    " ' q5  q6  q7  q8 
locate 10,8: print "+++++" '++
locate 10,9: print "    " ' q9  q10 q11 q12
locate 10,10:print "+++++" '++
locate 10,11:print "    " ' q13 q14 q15 q16
locate 10,12:print "+++++" '++
locate 4,16:print "magic square number = "
locate 8,1:print "**** MAGIC SQUARES 4x4 SOLVER ****"
locate 14,2:print "Freeware by prof. Daniele Mazza"
' q1....q16 are the actual values of each element of the square, as shown above
' s1....s16 are indeces that vary acoording to the variuos attemps to find q1...q16 values
' they refer to the position inside g16$....g1$
FOR i = 1 TO 16:g16$ = g16$ + CHR$(i):NEXT i ' start strig g16$ is generated in this line
nTot = 0 ' total number of squares is set to 0
' in the following 8 lines we impose some limits to the corner indeces
' in order to avoid magic squares obtained by rotation or mirroring of other existing
' q1 must be lowest value among (q1,q4,q13,q16), so cannot exceed 13
FOR s1 = 1 TO 13
scan
FOR s4 = s1 + 1 TO 16
scan
FOR s13 = s1 + 1 TO 16
scan
FOR s16 = s1 + 1 TO 16
scan
IF s1 = s4 OR s1 = s13 OR s1 = s16 OR s4 = s13 OR s4 = s16 OR s13 = s16 THEN 1000
IF s4 > s13 THEN 1000 ' il vertice q4 deve essere minore di q13
q1 = s1: q4 = s4: q13 = s13: q16 = s16
g12$ = ""
' here we produce g12$, which is then used to produce g11$...g10$... and so on
' it represents the elements still available (not present on the 4x4 square)
FOR i = 1 TO 16
scan
g1$ = MID$(g16$, i, 1)
IF i = s1 OR i = s4 OR i = s13 OR i = s16 THEN 100
g12$ = g12$ + g1$
100 NEXT i
' now we start the real job!
FOR s6 = 1 TO 12
scan ' position 6 chosen by iterative cycle
q6 = ASC(MID$(g12$, s6, 1))
g11$ = LEFT$(g12$, s6  1) + MID$(g12$, s6 + 1)
q11 = 34  q1  q6  q16 ' position 11 calculated
IF q11 < 1 OR q11 > 16 THEN 980
z = INSTR(g11$, CHR$(q11)): IF z = 0 THEN 980
g10$ = LEFT$(g11$, z  1) + MID$(g11$, z + 1)
FOR s10 = 1 TO 10
scan ' position 10 chosen by iterative cycle
q10 = ASC(MID$(g10$, s10, 1))
g9$ = LEFT$(g10$, s10  1) + MID$(g10$, s10 + 1)
q7 = 34  q4  q10  q13 ' position 7 calculated
IF q7 < 1 OR q7 > 16 THEN 970
z = INSTR(g9$, CHR$(q7)): IF z = 0 THEN 970
g8$ = LEFT$(g9$, z  1) + MID$(g9$, z + 1)
FOR s2 = 1 TO 8
scan ' position 2 chosen by iterative cycle
q2 = ASC(MID$(g8$, s2, 1))
g7$ = LEFT$(g8$, s2  1) + MID$(g8$, s2 + 1)
q3 = 34  q1  q2  q4 ' position 3 calculated
IF q3 < 1 OR q3 > 16 THEN 960
z = INSTR(g7$, CHR$(q3)): IF z = 0 THEN 960
g6$ = LEFT$(g7$, z  1) + MID$(g7$, z + 1)
q14 = 34  q2  q6  q10 ' position 14 calculated
IF q14 < 1 OR q14 > 16 THEN 960
z = INSTR(g6$, CHR$(q14)): IF z = 0 THEN 960
g5$ = LEFT$(g6$, z  1) + MID$(g6$, z + 1)
q15 = 34  q3  q7  q11 ' position 15 calculated
IF q15 < 1 OR q15 > 16 THEN 960
z = INSTR(g5$, CHR$(q15)): IF z = 0 THEN 960
g4$ = LEFT$(g5$, z  1) + MID$(g5$, z + 1)
FOR s5 = 1 TO 4
scan ' position 5 chosen by iterative cycle
q5 = ASC(MID$(g4$, s5, 1))
g3$ = LEFT$(g4$, s5  1) + MID$(g4$, s5 + 1)
q9 = 34  q1  q5  q13 ' position 9 calculated
IF q9 < 1 OR q9 > 16 THEN 950
z = INSTR(g3$, CHR$(q9)): IF z = 0 THEN 950
g2$ = LEFT$(g3$, z  1) + MID$(g3$, z + 1)
q8 = 34  q5  q6  q7 ' position 8 calculated
IF q8 < 1 OR q8 > 16 THEN 950
z = INSTR(g2$, CHR$(q8)): IF z = 0 THEN 950
g1$ = LEFT$(g2$, z  1) + MID$(g2$, z + 1)
q12 = 34  q9  q10  q11 ' position 12 calculated
IF q12 < 1 OR q12 > 16 THEN 950
IF ASC(g1$) <> q12 THEN 950
CALL writeIt ' we reached a regular magic square, so we write it down
nTot = nTot + 1: LOCATE 28,16 : PRINT nTot;
print #1, q1;" ";q2;" ";q3;" ";q4;" ";q5;" ";q6;" ";q7;" ";q8;" ";q9;" ";q10;" ";q11;" ";q12;" ";q13;" ";q14;" ";q15;" ";q16
950 NEXT s5
960 NEXT s2
970 NEXT s10
980 NEXT s6
1000 NEXT s16:NEXT s13:NEXT s4:NEXT s1
close #1
locate 1, 18 : print "One moment: Checking for duplicate lines in data file..."
'load magic Square data from file
dim dat$(nTot)
open "Magic Square 4 data.txt" for input as #1
while eof(#1) = 0
input #1, fline$
idx = idx + 1
dat$(idx) = fline$
wend
close #1
'check for duplicate lines
for i = 1 to idx 1
scan
for j = i + 1 to idx
scan
if dat$(i) = dat$(j) then
locate 1, 20
print "Square #";i;" duplicates Square #";j;" !!!"
end
end if
next
next
' print square # 678
locate 1, 20 : Print "Square #678 is: ";dat$(678)
locate 1, 22 : PRINT " > Job finished !! "
End
' sub's 
Sub writeIt
locate 12,5:print q1;" ":locate 18,5:print q2;" ":locate 24,5:print q3;" ":locate 30,5:print q4;" "
locate 12,7:print q5;" ":locate 18,7:print q6;" ":locate 24,7:print q7;" ":locate 30,7:print q8;" "
locate 12,9:print q9;" ":locate 18,9:print q10;" ":locate 24,9:print q11;" ":locate 30,9:print q12;" "
locate 12,11:print q13;" ":locate 18,11:print q14;" ":locate 24,11:print q15;" ":locate 30,11:print q16;" "
call checkIt
End Sub
sub checkIt
if q1 + q2 + q3 + q4 <> 34 then call stopIt 1
if q5 + q6 + q7 + q8 <> 34 then call stopIt 2
if q9 + q10 + q11 + q12 <> 34 then call stopIt 3
if q13 + q14 + q15 + q16 <> 34 then call stopIt 4
if q1 + q5 + q9 + q13 <> 34 then call stopIt 5
if q2 + q6 + q10 + q14 <> 34 then call stopIt 6
if q3 + q7 + q11 + q15 <> 34 then call stopIt 7
if q4 + q8 + q12 + q16 <> 34 then call stopIt 8
if q1 + q6 + q11 + q16 <> 34 then call stopIt 9
if q4 + q7 + q10 + q13 <> 34 then call stopIt 10
end sub
sub stopIt checkNo
close #1
print "Check No: ";checkNo;" failed to add up to 34."
end
end sub
Quote: magic square number = 880
One moment: Checking for duplicate lines in data file...
Square #678 is: 4 14 7 9 15 6 1 12 2 11 16 5 13 3 10 8
> Job finished !!




Logged

B+



danmaz
New Member
member is offline
Gender:
Posts: 5


Re: Magic Squares 4x4 Solver
« Reply #6 on: Sep 14^{th}, 2017, 1:32pm » 

Thanks for comments !!
I should remark that, as Richard said, the goto statements inside the many ( for..next ) loops are all directed to the proper next statement.
Using 'exit for' statement exits abruptly from the loop, the 'goto' simply skips some lines and remains inside the loop..as I need.
Actually I do not get the point about #678 magic square !! it looks pretty regular indeed..!
Yes, Rod, I already use LibertyBasic to calculate bond distances and angles for my molecular models!! very useful...
Thanks to 'bplus' for advices about 'scan' and saving to disk.
Daniele


Logged




bplus
Senior Member
member is offline
Gender:
Posts: 1290


Re: Magic Squares 4x4 Solver
« Reply #7 on: Sep 14^{th}, 2017, 3:05pm » 

Yes, 678 is pretty regular.
My point was that after flashing a bunch of numbers up on the screen, one should be able to pick one out and examine it or use it for some purpose.
Unless of course you are a math guy. In that case, don't tell Rod.


Logged

B+



danmaz
New Member
member is offline
Gender:
Posts: 5


Re: Magic Squares 4x4 Solver
« Reply #8 on: Sep 16^{th}, 2017, 05:45am » 

I think the best way should be to open a file for output and to write in there the 880 magic cubes in a 4x4 grid (with corresponding progressive nr.) The should appear ordered in position q1 (top left) ,then q2 (top right)


Logged




