Board Logo
« Magic Squares 4x4 Solver »

Welcome Guest. Please Login or Register.
Nov 20th, 2017, 6:43pm


Conforums Terms of Service | Membership Rules | Home | Search | Recent Posts | Notification | Format Your Message | Installation FAQ

Please use the forums Search feature before asking.
Please post code using the code box described in Format Your Messages.
This will keep indentation, separate it better form the message and prevent gibberish.
If the code is too long for one post or additional files are needed, upload a ZIP archive to the Just BASIC Files Archive Site.

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Magic Squares 4x4 Solver  (Read 301 times)
danmaz
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 5
xx Magic Squares 4x4 Solver
« Thread started on: Sep 12th, 2017, 08:05am »

Hi everybody

Here we deal with magics...magic square 4x4 generator
It takes 1 or 2 minutes to generate all combinations

Enjoy (tested several times, should be bugs-free)

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
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
 FOR s4 = s1 + 1 TO 16
 FOR s13 = s1 + 1 TO 16
 FOR s16 = s1 + 1 TO 16
 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
   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                               ' 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                               ' 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                                 ' 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                                  ' 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;
 950 NEXT s5
 960 NEXT s2
 970 NEXT s10
 980 NEXT s6
1000 NEXT s16:NEXT s13:NEXT s4:NEXT s1

 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;" "
End Sub

 
User IP Logged

Rod
Administrator
ImageImageImageImageImage


member is offline

Avatar

Graphics = Goosebumps!


PM

Gender: Male
Posts: 3129
xx Re: Magic Squares 4x4 Solver
« Reply #1 on: Sep 12th, 2017, 08:37am »

Nice, your next challenge is to draw a molecular model using Just BASIC's easy to use drawing commands! smiley 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 12th, 2017, 09:06am by Rod » User IP Logged

rtr
Member in Training
ImageImage


member is offline

Avatar




PM


Posts: 30
xx Re: Magic Squares 4x4 Solver
« Reply #2 on: Sep 12th, 2017, 1:11pm »

on Sep 12th, 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.
User IP Logged

bplus
Senior Member
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 1213
xx Re: Magic Squares 4x4 Solver
« Reply #3 on: Sep 12th, 2017, 6:38pm »

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

B+
Rod
Administrator
ImageImageImageImageImage


member is offline

Avatar

Graphics = Goosebumps!


PM

Gender: Male
Posts: 3129
xx Re: Magic Squares 4x4 Solver
« Reply #4 on: Sep 13th, 2017, 01:55am »

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

bplus
Senior Member
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 1213
xx Re: Magic Squares 4x4 Solver
« Reply #5 on: Sep 13th, 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 !!

User IP Logged

B+
danmaz
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 5
xx Re: Magic Squares 4x4 Solver
« Reply #6 on: Sep 14th, 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
User IP Logged

bplus
Senior Member
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 1213
xx Re: Magic Squares 4x4 Solver
« Reply #7 on: Sep 14th, 2017, 3:05pm »

Yes, 678 is pretty regular. smiley

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. wink
User IP Logged

B+
danmaz
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 5
xx Re: Magic Squares 4x4 Solver
« Reply #8 on: Sep 16th, 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)

smiley
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

Conforums Terms of Service | Membership Rules | Home | Search | Recent Posts | Notification | Format Your Message | Installation FAQ

Donate $6.99 for 50,000 Ad-Free Pageviews!

| |

This forum powered for FREE by Conforums ©
Sign up for your own Free Message Board today!
Terms of Service | Privacy Policy | Conforums Support | Parental Controls