Vorige Pagina About the Author

' Generates SelfOrthogonal Latin Diagonal Squares (8 x 8)
' Associated (Idempotent Squares)

' Tested with Office 365 under Windows 11

Sub SelfOrth8a()

Dim a(64), b(8), a1(8)
Dim b2(64), c(64), a0(8, 8)

y = MsgBox("Locked", vbCritical, "Routine SelfOrth8a")
End

n2 = 0: n9 = 0: k1 = 1: k2 = 1
m1 = 1: m2 = 8: s1 = 28: Pr8 = s1 / 4

For i1 = 1 To 8: a1(i1) = i1 - 1: Next i1
   
    Sheets("Klad1").Select
    
    t1 = Timer

For j64 = 8 To 8 ''m1 To m2                                      'a(64) 8 To 8 
    a(64) = a1(j64)
    a(1) = Pr8 - a(64)

For j63 = m1 To m2                                               'a(63)
    a(63) = a1(j63)
    If a(63) = a(64) Then GoTo 630

    a(2) = Pr8 - a(63)

For j62 = m1 To m2                                               'a(62)
    a(62) = a1(j62)
    If a(62) = a(63) Or a(62) = a(64) Then GoTo 620
     
    a(3) = Pr8 - a(62)
   
For j61 = m1 To m2                                               'a(61)
    a(61) = a1(j61)
    If a(61) = a(62) Or a(61) = a(63) Or a(61) = a(64) Then GoTo 610

    a(4) = Pr8 - a(61)

For j60 = m1 To m2                                               'a(60)
    a(60) = a1(j60)
    If a(60) = a(61) Or a(60) = a(62) Or a(60) = a(63) Or a(60) = a(64) Then GoTo 600
    If a(60) = a(4) Then GoTo 600

    a(5) = Pr8 - a(60)
    If a(5) = a(61) Then GoTo 600
     
For j59 = m1 To m2                                               'a(59)
    a(59) = a1(j59)
    If a(59) = a(60) Or a(59) = a(61) Or a(59) = a(62) Or a(59) = a(63) Or a(59) = a(64) Then GoTo 590
    If a(59) = a(3) Then GoTo 590
     
    a(6) = Pr8 - a(59)
    If a(6) = a(62) Then GoTo 590

For j58 = m1 To m2                                               'a(58)
    a(58) = a1(j58)
    If a(58) = a(59) Or a(58) = a(60) Or a(58) = a(61) Or a(58) = a(62) Or a(58) = a(63) Or a(58) = a(64) Then GoTo 580
    If a(58) = a(2) Then GoTo 580
     
    a(7) = Pr8 - a(58)
    If a(7) = a(63) Then GoTo 580

    a(57) = s1 - a(58) - a(59) - a(60) - a(61) - a(62) - a(63) - a(64)
    If a(57) < a1(m1) Or a(57) > a1(m2) Then GoTo 580
    If a(57) = a(1) Then GoTo 580

    a(8) = Pr8 - a(57)
    If a(8) = a(64) Then GoTo 580

For j56 = m1 To m2                                               'a(56)
    a(56) = a1(j56)
    If a(56) = a(64) Or a(56) = a(8) Then GoTo 560

    a(9) = Pr8 - a(56)
    If a(9) = a(1) Or a(9) = a(57) Then GoTo 560

For j55 = 7 To 7 ''m1 To m2                                      'a(55)7 To 7 
    a(55) = a1(j55)
    If a(55) = a(56) Then GoTo 550
    If a(55) = a(63) Or a(55) = a(7) Then GoTo 550
    If a(55) = a(64) Or a(55) = a(1) Then GoTo 550                     'Diagonal 1

    a(10) = Pr8 - a(55)
    If a(10) = a(2) Or a(10) = a(58) Then GoTo 550
    If a(10) = a(1) Or a(10) = a(55) Or a(10) = a(64) Then GoTo 550    'Diagonal 1

For j54 = m1 To m2                                               'a(54)
    a(54) = a1(j54)
    If a(54) = a(55) Or a(54) = a(56) Then GoTo 540
    If a(54) = a(62) Or a(54) = a(6) Then GoTo 540
 
    a(11) = Pr8 - a(54)
    If a(11) = a(3) Or a(11) = a(59) Then GoTo 540

For j53 = m1 To m2                                               'a(53)
    a(53) = a1(j53)
    If a(53) = a(54) Or a(53) = a(55) Or a(53) = a(56) Then GoTo 530
    If a(53) = a(61) Or a(53) = a(5) Then GoTo 530

    a(12) = Pr8 - a(53)
    If a(12) = a(4) Or a(12) = a(60) Then GoTo 530

For j52 = m1 To m2                                               'a(52)
    a(52) = a1(j52)
    If a(52) = a(53) Or a(52) = a(54) Or a(52) = a(55) Or a(52) = a(56) Then GoTo 520
    If a(52) = a(4) Or a(52) = a(12) Or a(52) = a(60) Then GoTo 520

    a(13) = Pr8 - a(52)
    If a(13) = a(5) Or a(13) = a(53) Or a(13) = a(61) Then GoTo 520
    
For j51 = m1 To m2                                               'a(51)
    a(51) = a1(j51)
    If a(51) = a(52) Or a(51) = a(53) Or a(51) = a(54) Or a(51) = a(55) Or a(51) = a(56) Then GoTo 510
    If a(51) = a(3) Or a(51) = a(11) Or a(51) = a(59) Then GoTo 510
     
    a(14) = Pr8 - a(51)
    If a(14) = a(6) Or a(14) = a(54) Or a(14) = a(62) Then GoTo 510

For j50 = m1 To m2                                               'a(50)
    a(50) = a1(j50)
    If a(50) = a(51) Or a(50) = a(52) Or a(50) = a(53) Or a(50) = a(54) Or a(50) = a(55) Or a(50) = a(56) Then GoTo 500
    If a(50) = a(2) Or a(50) = a(10) Or a(50) = a(58) Then GoTo 500
    If a(50) = a(8) Or a(50) = a(57) Then GoTo 500                      'Diagonal 2

    a(15) = Pr8 - a(50)
    If a(15) = a(7) Or a(15) = a(55) Or a(15) = a(63) Then GoTo 500
    If a(15) = a(8) Or a(15) = a(50) Or a(15) = a(57) Then GoTo 500     'Diagonal 2

    a(49) = s1 - a(50) - a(51) - a(52) - a(53) - a(54) - a(55) - a(56)
    If a(49) < a1(m1) Or a(49) > a1(m2) Then GoTo 500
    If a(49) = a(1) Or a(49) = a(9) Or a(49) = a(57) Then GoTo 500

    a(16) = Pr8 - a(49)
    If a(16) = a(8) Or a(16) = a(56) Or a(16) = a(64) Then GoTo 500

For j48 = m1 To m2                                               'a(48)
    a(48) = a1(j48)
    If a(48) = a(64) Or a(48) = a(8) Or a(48) = a(56) Or a(48) = a(16) Then GoTo 480

    a(17) = Pr8 - a(48)
    If a(17) = a(1) Or a(17) = a(57) Or a(17) = a(9) Or a(17) = a(49) Then GoTo 480

For j47 = m1 To m2                                               'a(47)
    a(47) = a1(j47)
    If a(47) = a(48) Then GoTo 470
    If a(47) = a(63) Or a(47) = a(7) Or a(47) = a(55) Or a(47) = a(15) Then GoTo 470

    a(18) = Pr8 - a(47)
    If a(18) = a(2) Or a(18) = a(58) Or a(18) = a(10) Or a(18) = a(50) Then GoTo 470

For j46 = 6 To 6 ''m1 To m2                                      'a(46) 6 To 6 ''
    a(46) = a1(j46)
    If a(46) = a(47) Or a(46) = a(48) Then GoTo 460
    If a(46) = a(62) Or a(46) = a(6) Or a(46) = a(54) Or a(46) = a(14) Then GoTo 460
    If a(46) = a(64) Or a(46) = a(1) Or a(46) = a(55) Or a(46) = a(10) Then GoTo 460    'Diagonal 1
 
    a(19) = Pr8 - a(46)
    If a(19) = a(3) Or a(19) = a(59) Or a(19) = a(11) Or a(19) = a(51) Then GoTo 460
    If a(19) = a(1) Or a(19) = a(10) Or a(19) = a(46) Or a(19) = a(55) Or a(19) = a(64) Then GoTo 460     'Diagonal 1

For j45 = m1 To m2                                               'a(45)
    a(45) = a1(j45)
    If a(45) = a(46) Or a(45) = a(47) Or a(45) = a(48) Then GoTo 450
    If a(45) = a(61) Or a(45) = a(5) Or a(45) = a(53) Or a(45) = a(13) Then GoTo 450

    a(20) = Pr8 - a(45)
    If a(20) = a(4) Or a(20) = a(60) Or a(20) = a(12) Or a(20) = a(52) Then GoTo 450

For j44 = m1 To m2                                               'a(44)
    a(44) = a1(j44)
    If a(44) = a(45) Or a(44) = a(46) Or a(44) = a(47) Or a(44) = a(48) Then GoTo 440
    If a(44) = a(4) Or a(44) = a(12) Or a(44) = a(60) Or a(44) = a(20) Or a(44) = a(52) Then GoTo 440

    a(21) = Pr8 - a(44)
    If a(21) = a(5) Or a(21) = a(53) Or a(21) = a(61) Or a(21) = a(13) Or a(21) = a(45) Then GoTo 440
    
For j43 = m1 To m2                                               'a(43)
    a(43) = a1(j43)
    If a(43) = a(44) Or a(43) = a(45) Or a(43) = a(46) Or a(43) = a(47) Or a(43) = a(48) Then GoTo 430
    If a(43) = a(3) Or a(43) = a(11) Or a(43) = a(59) Or a(43) = a(19) Or a(43) = a(51) Then GoTo 430
    If a(43) = a(8) Or a(43) = a(57) Or a(43) = a(15) Or a(43) = a(50) Then GoTo 430                      'Diagonal 2
     
    a(22) = Pr8 - a(43)
    If a(22) = a(6) Or a(22) = a(54) Or a(22) = a(62) Or a(22) = a(14) Or a(22) = a(46) Then GoTo 430
    If a(22) = a(8) Or a(22) = a(50) Or a(22) = a(57) Or a(22) = a(15) Or a(22) = a(43) Then GoTo 430     'Diagonal 2

For j42 = m1 To m2                                               'a(42)
    a(42) = a1(j42)
    If a(42) = a(43) Or a(42) = a(44) Or a(42) = a(45) Or a(42) = a(46) Or a(42) = a(47) Or a(42) = a(48) Then GoTo 420
    If a(42) = a(2) Or a(42) = a(10) Or a(42) = a(58) Or a(42) = a(18) Or a(42) = a(50) Then GoTo 420

    a(23) = Pr8 - a(42)
    If a(23) = a(7) Or a(23) = a(55) Or a(23) = a(63) Or a(23) = a(15) Or a(23) = a(47) Then GoTo 420

    a(41) = s1 - a(42) - a(43) - a(44) - a(45) - a(46) - a(47) - a(48)
    If a(41) < a1(m1) Or a(41) > a1(m2) Then GoTo 420
    If a(41) = a(1) Or a(41) = a(9) Or a(41) = a(57) Or a(41) = a(17) Or a(41) = a(49) Then GoTo 420

    a(24) = Pr8 - a(41)
    If a(24) = a(8) Or a(24) = a(56) Or a(24) = a(64) Or a(24) = a(16) Or a(24) = a(48) Then GoTo 420

For j40 = m1 To m2                                               'a(40)
    a(40) = a1(j40)
    If a(40) = a(64) Or a(40) = a(8) Or a(40) = a(56) Or a(40) = a(16) Or a(40) = a(48) Or a(40) = a(24) Then GoTo 400
    
    a(25) = Pr8 - a(40)
    If a(25) = a(1) Or a(25) = a(57) Or a(25) = a(9) Or a(25) = a(49) Or a(25) = a(17) Or a(25) = a(41) Then GoTo 400
    
For j39 = m1 To m2                                               'a(39)
    a(39) = a1(j39)
    If a(39) = a(40) Then GoTo 390
    
    If a(39) = a(63) Or a(39) = a(7) Or a(39) = a(55) Or a(39) = a(15) Or a(39) = a(47) Or a(39) = a(23) Then GoTo 390
    
    a(26) = Pr8 - a(39)
    If a(26) = a(2) Or a(26) = a(58) Or a(26) = a(10) Or a(26) = a(50) Or a(26) = a(18) Or a(26) = a(42) Then GoTo 390

For j38 = m1 To m2                                               'a(38)
    a(38) = a1(j38)
    If a(38) = a(39) Or a(38) = a(40) Then GoTo 380

    If a(38) = a(62) Or a(38) = a(6) Or a(38) = a(54) Or a(38) = a(14) Or a(38) = a(46) Or a(38) = a(22) Then GoTo 380

    a(27) = Pr8 - a(38)
    If a(27) = a(3) Or a(27) = a(59) Or a(27) = a(11) Or a(27) = a(51) Or a(27) = a(19) Or a(27) = a(43) Then GoTo 380

    a(37) = -a(38) - a(39) - a(40) - a(45) - a(46) - a(47) - a(48) + a(49) + a(50) + a(51) + a(52) + a(57) + a(58) + a(59) + a(60)
    If a(37) < a1(m1) Or a(37) > a1(m2) Then GoTo 380
   
    If a(37) = a(38) Or a(37) = a(39) Or a(37) = a(40) Then GoTo 380
    If a(37) = a(61) Or a(37) = a(5) Or a(37) = a(53) Or a(37) = a(13) Or a(37) = a(45) Or a(37) = a(21) Then GoTo 380
    
    If a(37) <> 4 Then GoTo 380 'Option for Idempotent Squares

    a(28) = Pr8 - a(37)
    If a(28) = a(4) Or a(28) = a(60) Or a(28) = a(12) Or a(28) = a(52) Or a(28) = a(20) Or a(28) = a(44) Then GoTo 380
    If a(28) = a(1) Or a(28) = a(10) Or a(28) = a(19) Or a(28) = a(37) Or a(28) = a(46) Or a(28) = a(55) Or a(28) = a(64) Then GoTo 380 

    a(36) = a(37) - a(44) + a(45) - a(52) + a(53) - a(60) + a(61)
    If a(36) < a1(m1) Or a(36) > a1(m2) Then GoTo 380

    If a(36) = a(37) Or a(36) = a(38) Or a(36) = a(39) Or a(36) = a(40) Then GoTo 380
    If a(36) = a(60) Or a(36) = a(4) Or a(36) = a(52) Or a(36) = a(12) Or a(36) = a(44) Or a(36) = a(20) Or a(36) = a(28) Then GoTo 380

    a(29) = Pr8 - a(36)
    If a(29) = a(5) Or a(29) = a(61) Or a(29) = a(13) Or a(29) = a(53) Or a(29) = a(21) Or a(29) = a(45) Or a(29) = a(37) Then GoTo 380
    If a(29) = a(8) Or a(29) = a(15) Or a(29) = a(22) Or a(29) = a(36) Or a(29) = a(43) Or a(29) = a(50) Or a(29) = a(57) Then GoTo 380 

    a(35) = a(38) - a(43) + a(46) - a(51) + a(54) - a(59) + a(62)
    If a(35) < a1(m1) Or a(35) > a1(m2) Then GoTo 380

    If a(35) = a(36) Or a(35) = a(37) Or a(35) = a(38) Or a(35) = a(39) Or a(35) = a(40) Then GoTo 380
    If a(35) = a(59) Or a(35) = a(3) Or a(35) = a(51) Or a(35) = a(11) Or a(35) = a(43) Or a(35) = a(19) Or a(35) = a(27) Then GoTo 380

    a(30) = Pr8 - a(35)
    If a(30) = a(6) Or a(30) = a(62) Or a(30) = a(14) Or a(30) = a(54) Or a(30) = a(22) Or a(30) = a(46) Or a(30) = a(38) Then GoTo 380

    a(34) = a(39) - a(42) + a(47) - a(50) + a(55) - a(58) + a(63)
    If a(34) < a1(m1) Or a(34) > a1(m2) Then GoTo 380

    If a(34) = a(35) Or a(34) = a(36) Or a(34) = a(37) Or a(34) = a(38) Or a(34) = a(39) Or a(34) = a(40) Then GoTo 380
    If a(34) = a(58) Or a(34) = a(2) Or a(34) = a(50) Or a(34) = a(10) Or a(34) = a(42) Or a(34) = a(18) Or a(34) = a(26) Then GoTo 380

    a(31) = Pr8 - a(34)
    If a(31) = a(7) Or a(31) = a(63) Or a(31) = a(15) Or a(31) = a(55) Or a(31) = a(23) Or a(31) = a(47) Or a(31) = a(39) Then GoTo 380

    a(33) = s1 - a(34) - a(35) - a(36) - a(37) - a(38) - a(39) - a(40)
    If a(33) < a1(m1) Or a(33) > a1(m2) Then GoTo 380

    a(32) = Pr8 - a(33)
    
    GoSub 1800: If fl1 = 0 Then GoTo 5  'Check Latin Rpws, Columns and Diagonals
     
    GoSub 1500: If fl1 = 0 Then GoTo 5  'Check Self Orthogonal

     
      n9 = n9 + 1: ''GoSub 2650: End
      
      Cells(1, 1).Value = n9
      Cells(2, 1).Value = a(64)

5

380 Next j38
390 Next j39
400 Next j40

420 Next j42
430 Next j43
440 Next j44
450 Next j45
460 Next j46
470 Next j47
480 Next j48

500 Next j50
510 Next j51
520 Next j52
530 Next j53
540 Next j54
550 Next j55
560 Next j56

580 Next j58
590 Next j59
600 Next j60
610 Next j61
620 Next j62
630 Next j63
640 Next j64

    t2 = Timer
    
    t10 = Str(t2 - t1) + " sec., " + Str(n9) + " Solutions for sum" + Str(s1)
    y = MsgBox(t10, 0, "Routine SelfOrth8a")

End

'   Exclude solutions with identical numbers in rows, columns, diagonals

1800

'    Rows
    
     i1 = -7
     For i0 = 1 To 8
         i1 = i1 + 8
         b(1) = a(i1):     b(2) = a(i1 + 1): b(3) = a(i1 + 2): b(4) = a(i1 + 3):
         b(5) = a(i1 + 4): b(6) = a(i1 + 5): b(7) = a(i1 + 6): b(8) = a(i1 + 7)
         GoSub 1860: If fl1 = 0 Then Return
     Next i0

'    Columns
    
     i1 = 0
     For i0 = 1 To 8
         i1 = i1 + 1
         b(1) = a(i1):      b(2) = a(i1 + 8):  b(3) = a(i1 + 16): b(4) = a(i1 + 24):
         b(5) = a(i1 + 32): b(6) = a(i1 + 40): b(7) = a(i1 + 48): b(8) = a(i1 + 56)
         GoSub 1860: If fl1 = 0 Then Return
     Next i0

'    Main Diagonals

     b(1) = a(1): b(2) = a(10): b(3) = a(19): b(4) = a(28): b(5) = a(37): b(6) = a(46): b(7) = a(55): b(8) = a(64)
     GoSub 1860: If fl1 = 0 Then Return
     b(1) = a(8): b(2) = a(15): b(3) = a(22): b(4) = a(29): b(5) = a(36): b(6) = a(43): b(7) = a(50): b(8) = a(57)
     GoSub 1860: If fl1 = 0 Then Return
    
     Return
    
'    Check identical numbers
    
1860 fl1 = 1
     For j10 = 1 To 8
        b20 = b(j10)
        For j20 = (1 + j10) To 8
            If b20 = b(j20) Then fl1 = 0: Return
        Next j20
     Next j10
     Return
    
'   Print results (selected numbers)

2645 For i1 = 1 To 64
         Cells(n9, i1).Value = a(i1)
     Next i1
     Cells(n9, 65).Value = n9
     Cells(1, 66).Value = n9
     Return

'    Print results (squares)

2650 n2 = n2 + 1
     If n2 = 5 Then
         n2 = 1: k1 = k1 + 9: k2 = 1
     Else
         If n9 > 1 Then k2 = k2 + 9
     End If
     
     Cells(k1, k2 + 1).Font.Color = -4165632
     Cells(k1, k2 + 1).Value = n9
    
     i3 = 0
     For i1 = 1 To 8
         For i2 = 1 To 8
             i3 = i3 + 1
             Cells(k1 + i1, k2 + i2).Value = a(i3)
         Next i2
     Next i1
    
     Return

'    Check Self Orthogonal

1500 fl1 = 1

'    Transpose a()

     i3 = 0: Erase a0
     For i1 = 1 To 8
     For i2 = 1 To 8
         i3 = i3 + 1
         a0(i1, i2) = a(i3)
     Next i2
     Next i1
    
     i3 = 0:
     For i1 = 1 To 8
     For i2 = 1 To 8
         i3 = i3 + 1
         b2(i3) = a0(i2, i1)
     Next i2
     Next i1
    
'    Calculate c()
    
     Erase c
     For i1 = 1 To 64
         c(i1) = 8 * a(i1) + b2(i1) + 1
     Next i1

     fl1 = 1: n20 = 0
     For j1 = 1 To 64
        a20 = c(j1):
        For j2 = (1 + j1) To 64
            If a20 = c(j2) Then fl1 = 0: Return
        Next j2
1510 Next j1

     Return

End Sub

Vorige Pagina About the Author