Ungerade Seitenlänge

 

Ein Magisches Quadrat hat eine ungerade Seitenlänge, wenn diese nicht durch 2 teilbar ist, so zum Beispiel 3, 5, 7.

Um beispielsweise ein Magisches Quadrat mit der Seitenlänge 5 zu erstellen, bereitet man sich ein 5x5 Quadrat vor.

         
         
         
         
         

Dann dreht man dieses Quadrat um 45°.

 
   
     
       
         
       
     
   
 

Ist diese Vorarbeit getan, so trägt man diagonal von oben Mitte nach links Mitte nach unten Mitte die Zahlen von 1 bis zum Quadrat der Seitenlänge ein. Bei diesem Beispiel sind es die Zahlen von 1 bis 25.

1
2   6
3   7   11
4   8   12   16
5   9   13   17   21
10   14   18   22
15   19   23
20   24
25

Um ein normales 5x5 Quadrat zu erhalten, müsste man die Ecken des bisherigen Quadrates abschneiden. In diesen Ecken liegen aber noch Zahlen.

1
2   6
3   7   11
4   8   12   16
5   9   13   17   21
10   14   18   22
15   19   23
20   24
25

Diese Zahlen werden jetzt um die Seitenlänge in die freien Zellen verschoben.

 
   
3 20 7 24 11
  16 8 25 12 4  
  9 21 13 5 17  
  22 14 1 18 20  
15 2 19 6 23
   
 

Und schon ist das Magische 5x5 Quadrat fertig.

16.Mai.2002 18:43
3 20 7 24 11
16 8 25 12 4
9 21 13 5 17
22 14 1 18 20
15 2 19 6 23

Umsetzung in Delphi

Für das Erstellen eines Magischen Quadrates mit ungerader Seitenlänge sind zwei Größen wichtig. Zum einen die Größe des überlappenden Dreiecks, die in der Prozedur mit halfsqr bezeichnet wird, zum anderen der Platz, den das um 45° gedrehte Quadrat einnimmt, der in der Prozedur mit helpsqr bezeichnet wird.

Grundlage für die Prozedur ist eine For .. To .. Do Schleife, die von 1 bis zum Quadrat der Seitenlänge läuft. In dieser Schleife werden die Koordinaten a und b so verändert, dass sie zur nächsten Zelle immer diagonal nach links unten springen. Nur wenn die einzutragende Zahl n durch die Seitenlänge teilbar ist, muss eine neue Diagonale angefangen werden.

Während die Zahlen eingetragen werden, gehen die Koordinaten immer wieder über das eigentliche Magische Quadrat hinaus in die Randdreiecke. Die Prozedur prüft, in welchem Randdreieck sich die Zelle gerade befindet und verschiebt sie dann dementsprechend.

  • Spalte kleiner als halfsqr
    a<halfsqr
Verschiebung um eine Seitenlänge nach rechts
[a+size,b]
 
   
     
         
           
         
     
   
 
  • Spalte größer als halfsqr+size bzw. helpsqr-halfsqr
    a>helpsqr-halfsqr
Verschiebung um eine Seitenlänge nach links
[a-size,b]
 
   
     
         
           
         
     
   
 
  • Zeile kleiner als halfsqr
    b<halfsqr
Verschiebung um eine Seitenlänge nach unten
[a,b+size]
 
   
     
       
         
         
         
   
 
  • Zeile größer als halfsqr+size bzw. helpsqr-halfsqr
    b>helpsqr-halfsqr
Verschiebung um eine Seitenlänge nach oben
[a,b+size]
 
   
         
         
         
       
     
   
 

Im Allgemeinen muss das Magische Quadrat sowieso noch verschoben werden, nämlich vom Zentrum des um 45° gedrehten Quadrates in die obere linke Ecke - um halfsqr nach oben links.

 
   
         
             
             
             
         
   
 
         
           
           
             
             
       
     
   
 

Deshalb müssen alle Koordinaten [a,b] auf [a-halfsqr,b-halfsqr] umgeändert werden.

var
  MagSquare:Array[0..99{Spalten},0..99{Zeilen}] Of Word;
  n:word;
  size,a{Spalte},b{Zeile}:byte;

procedure tfrmCreateMagSquar.CreateOddMS;

var
  helpsqr:Word;
  halfsqr:byte;

begin
  halfsqr:=Size div 2;
  helpsqr:=2*size-1;
  a:=size;
  b:=1;
  For n:=1 to Sqr(Size) do
  begin
    if a<=halfsqr then magsquare[a+size-halfsqr-1,b-halfsqr-1]:=n;
    if a>helpsqr-halfsqr then magsquare[a-size-halfsqr-1,b-halfsqr-1]:=n;
    if b<=halfsqr then magsquare[a-halfsqr-1,b+size-halfsqr-1]:=n;
    if b>helpsqr-halfsqr then magsquare[a-halfsqr-1,b-size-halfsqr-1]:=n;
    if ((a>halfsqr) and (a<=helpsqr-halfsqr)) and ((b>halfsqr) and (b<=helpsqr-halfsqr)) then magsquare[a-halfsqr-1,b-halfsqr-1]:=n;
    if (n/size)=(n div size) then
    begin
      b:=b-size+2;
      a:=a+size;
    end
    else
    begin
      a:=a-1;
      b:=b+1;
    end;
  end;
end;