Gerade Seitenlänge

Ein Magisches Quadrat hat eine gerade Seitenlänge, wenn sie nur durch 2, nicht aber durch vier, teilbar ist, so zum Beispiel 6, 10, 14.

Um beispielsweise ein Magisches Quadrat mit der Seitenlänge 10 zu erstellen muss man auf eine Magisches 5x5 Quadrat zurückgreifen.

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

Nun addiert man zu diesem 5x5 Quadrat einmal das Quadrat der Seitenlänge, man erhält damit ein Magisches 5x5 Quadrat mit den Zahlen von 26-50. Dann braucht man noch ein Magisches 5x5 Quadrat mit den Zahlen von 51-75 und eins mit den Zahlen von 76-100. Man erhält diese, in dem man 2 bzw. 3 mal das Quadrat der Seitenlänge zu jeder Zahl des 5x5 Quadrat addiert.

28 45 32 49 36
41 33 50 37 29
34 46 38 30 42
47 39 26 43 35
40 27 44 31 48
53 70 57 74 61
66 58 75 62 54
59 71 63 55 67
72 64 51 68 70
65 52 69 56 73
78 95 82 99 86
91 83 100 87 79
84 96 88 80 92
97 89 76 93 85
90 77 94 81 98

Diese Quadrate ordnet man so an, dass man folgendes 10x10 Quadrat erhält:

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
53 70 57 74 61
66 58 75 62 54
59 71 63 55 67
72 64 51 68 70
65 52 69 56 73
78 95 82 99 86
91 83 100 87 79
84 96 88 80 92
97 89 76 93 85
90 77 94 81 98
28 45 32 49 36
41 33 50 37 29
34 46 38 30 42
47 39 26 43 35
40 27 44 31 48

Die Seitensummen in der Vertikalen stimmen jetzt schon miteinander überein. Nur die Horizontalen sind in der ersten Hälfte größer als in der unteren. Deshalb müssen jetzt noch Zahlen von oben nach unten, bzw. von unten nach oben getauscht werden, um ein Magisches Quadrat zu erhalten.

Vom Erstellen des Magischen Quadrates ist eine Zahl bekannt: die Größe des Dreiecks, das außerhalb des ungeraden Magischen Quadrates liegt. Sie ist abhängig von der Seitenlänge a und berechnet sich aus:

h = (a - 1) / 2

Diese Zahl bestimmt jetzt welche und wie viele Spalten getauscht werden müssen. In diesem Beispiel ist h = 2.

3 20 7 24 11 53 70 57 74 61
16 8 25 12 4 66 58 75 62 54
9 21 13 5 17 59 71 63 55 67
22 14 1 18 20 72 64 51 68 70
15 2 19 6 23 65 52 69 56 73
78 95 82 99 86 28 45 32 49 36
91 83 100 87 79 41 33 50 37 29
84 96 88 80 92 34 46 38 30 42
97 89 76 93 85 47 39 26 43 35
90 77 94 81 98 40 27 44 31 48

Das bedeutet: Es werden a Zeilen in h Spalten am Anfang der Tabelle vertauscht, außer in der Zeile (h + 1), dort ist es um eine Zelle verschoben. In diesem Beispiel bedeutet das also: Es werden 5 Zeilen in Spalte 1 und 2 vertauscht, außer in der 3. Zeile, da sind es die Spalten 2 und 3. Außerdem werden a Zellen in (h - 1) Spalten am Ende des Magischen Quadrates vertauscht. In diesem Quadrat betrifft das nur die 5 Zellen der Spalte 10.

78 95 7 24 11 53 70 57 74 36
91 83 25 12 4 66 58 75 62 29
9 96 88 5 17 59 71 63 55 42
97 89 1 18 20 72 64 51 68 35
90 77 19 6 23 65 52 69 56 48
3 20 82 99 86 28 45 32 49 61
16 8 100 87 79 41 33 50 37 54
84 21 13 80 92 34 46 38 30 67
22 14 76 93 85 47 39 26 43 70
15 2 94 81 98 40 27 44 31 73

Umsetzung in Delphi

Bevor der Algorithmus loslegen kann, muss er erst einmal die Seitenlänge halbieren, da ungerade Magische Quadrate die Grundlage für diesen Algorithmus sind. Am Ende wird die Seitenlänge dann wieder zurückgesetzt.

Der Quelltext für das Erstellen eines Magischen Quadrates mit gerader Seitenlänge besteht aus 2 Teilen.

Im ersten Teil werden gleichzeitig vier ungerade Magische Quadrate erstellt. Dabei wurde der Algorithmus für das Erstellen von ungeraden Magischen Quadraten so abgeändert, dass anstelle einer Zahl gleich vier Zahlen auf einmal eingetragen werden. Dabei handelt es sich um Zahlen die sich nur um Vielfache des Quadrates der Seitenlänge unterscheiden. Ein solches Verfahren spart hauptsächlich Zeit im Gegensatz dazu jedes Magische Quadrat einzeln erstellen zu müssen. Die vier Zahlen werden wie folgt in das Magische Quadrat eingetragen:

nn + 2 x Sqr(Size)
n + 3 x Sqr(Size)n + Sqr(Size)

Im zweiten Teil werden wie oben beschrieben bestimmte Zahlen getauscht. Es wird dabei zeilenweise vorgegangen und alle Zahlen einer Spalte mit den um eine Seitenlänge darunter liegenden Zahlen getauscht, bevor es zur nächsten Spalte geht. Dabei muss noch einmal unterschieden werden, in welcher Zeile sich der Algorithmus gerade befindet. Ist er nämlich in der Zeile halfsqr, dann müssen alle Spalten um 1 verschoben werden.

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

procedure tfrmCreateMagSquar.CreateEvenMS;

var
  helpsqr,halfsqr:Byte;
  h:Word;

begin
  size:=size div 2;
  halfsqr:=Size div 2;
  helpsqr:=2*size-1;
  a:=size;
  b:=1;
  for n:=1 to Sqr(Size) do
  begin
    if a<=halfsqr then
    begin
      magsquare[a+size-halfsqr-1,b-halfsqr-1]:=n;
      magsquare[a+size-halfsqr-1+size,b-halfsqr-1+size]:=n+Sqr(size);
      magsquare[a+size-halfsqr-1+size,b-halfsqr-1]:=n+2*Sqr(size);
      magsquare[a+size-halfsqr-1,b-halfsqr-1+size]:=n+3*Sqr(size);
    end;
    if a>helpsqr-halfsqr then
    begin
      magsquare[a-size-halfsqr-1,b-halfsqr-1]:=n;
      magsquare[a-size-halfsqr-1+size,b-halfsqr-1+size]:=n+Sqr(size);
      magsquare[a-size-halfsqr-1+size,b-halfsqr-1]:=n+2*Sqr(size);
      magsquare[a-size-halfsqr-1,b-halfsqr-1+size]:=n+3*Sqr(size);
    end;
    if b<=halfsqr then
    begin
      magsquare[a-halfsqr-1,b+size-halfsqr-1]:=n;
      magsquare[a-halfsqr-1+size,b+size-halfsqr-1+size]:=n+Sqr(size);
      magsquare[a-halfsqr-1+size,b+size-halfsqr-1]:=n+2*Sqr(size);
      magsquare[a-halfsqr-1,b+size-halfsqr-1+size]:=n+3*Sqr(size);
    end;
    if b>helpsqr-halfsqr then
    begin
      magsquare[a-halfsqr-1,b-size-halfsqr-1]:=n;
      magsquare[a-halfsqr-1+size,b-size-halfsqr-1+size]:=n+Sqr(size);
      magsquare[a-halfsqr-1+size,b-size-halfsqr-1]:=n+2*Sqr(size);
      magsquare[a-halfsqr-1,b-size-halfsqr-1+size]:=n+3*Sqr(size);
    end;
    if ((a>halfsqr) and (a<=helpsqr-halfsqr)) and ((b>halfsqr) and (b<=helpsqr-halfsqr)) then
    begin
      magsquare[a-halfsqr-1,b-halfsqr-1]:=n;
      magsquare[a-halfsqr-1+size,b-halfsqr-1+size]:=n+Sqr(size);
      magsquare[a-halfsqr-1+size,b-halfsqr-1]:=n+2*Sqr(size);
      magsquare[a-halfsqr-1,b-halfsqr-1+size]:=n+3*Sqr(size);
    end;
    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;
  for a:=0 to halfsqr-1 do
  begin
    for b:=0 to size-1 do
    begin
      if b=halfsqr then
      begin
        h:=magsquare[a+1,b];
        magsquare[a+1,b]:=magsquare[a+1,b+size];
        magsquare[a+1,b+size]:=h;
      end
      else
      begin
        h:=magsquare[a,b];
        magsquare[a,b]:=magsquare[a,b+size];
        magsquare[a,b+size]:=h;
      end;
      if a>0 then
      begin
        h:=magsquare[a+size+halfsqr+1,b];
        magsquare[a+size+halfsqr+1,b]:=magsquare[a+size+halfsqr+1,b+size];
        magsquare[a+size+halfsqr+1,b+size]:=h;
      end;
    end;
  end;
  Size:=size * 2;
end;