Magic squares of singly even order: Difference between revisions
Thundergnat (talk | contribs) m (→{{header|Perl 6}}: Replace accidentally removed header) |
(added FreeBASIC) |
||
Line 12: | Line 12: | ||
* [http://www.1728.org/magicsq3.htm Singly Even Magic Squares (1728.org)]<br><br> |
* [http://www.1728.org/magicsq3.htm Singly Even Magic Squares (1728.org)]<br><br> |
||
=={{header|FreeBASIC}}== |
|||
<lang freebasic>' version 18-03-2016 |
|||
' compile with: fbc -s console |
|||
' singly even magic square 6, 10, 14, 18... |
|||
Sub Err_msg(msg As String) |
|||
Print msg |
|||
Beep : Sleep 5000, 1 : Exit Sub |
|||
End Sub |
|||
Sub se_magicsq(n As UInteger, filename As String = "") |
|||
' filename <> "" then save square in a file |
|||
' filename can contain directory name |
|||
' if filename exist it will be overwriten, no error checking |
|||
If n < 6 Then |
|||
Err_msg( "Error: n is to small") |
|||
Exit Sub |
|||
End If |
|||
If ((n -2) Mod 4) <> 0 Then |
|||
Err_msg "Error: not possible to make singly" + _ |
|||
" even magic square size " + Str(n) |
|||
Exit Sub |
|||
End If |
|||
Dim As UInteger sq(1 To n, 1 To n) |
|||
Dim As UInteger magic_sum = n * (n ^ 2 +1) \ 2 |
|||
Dim As UInteger sq_d_2 = n \ 2, q2 = sq_d_2 ^ 2 |
|||
Dim As UInteger l = (n -2) \ 4 |
|||
Dim As UInteger x = sq_d_2 \ 2 + 1, y = 1, nr = 1 |
|||
Dim As String frmt = String(Len(Str(n * n)) +1, "#") |
|||
' fill pattern A C |
|||
' D B |
|||
' main loop for creating magic square in section A |
|||
' the value for B,C and D is derived from A |
|||
' uses the FreeBASIC odd order magic square routine |
|||
Do |
|||
If sq(x, y) = 0 Then |
|||
sq(x , y ) = nr ' A |
|||
sq(x + sq_d_2, y + sq_d_2) = nr + q2 ' B |
|||
sq(x + sq_d_2, y ) = nr + q2 * 2 ' C |
|||
sq(x , y + sq_d_2) = nr + q2 * 3 ' D |
|||
If nr Mod sq_d_2 = 0 Then |
|||
y += 1 |
|||
Else |
|||
x += 1 : y -= 1 |
|||
End If |
|||
nr += 1 |
|||
End If |
|||
If x > sq_d_2 Then |
|||
x = 1 |
|||
Do While sq(x,y) <> 0 |
|||
x += 1 |
|||
Loop |
|||
End If |
|||
If y < 1 Then |
|||
y = sq_d_2 |
|||
Do While sq(x,y) <> 0 |
|||
y -= 1 |
|||
Loop |
|||
End If |
|||
Loop Until nr > q2 |
|||
' swap left side |
|||
For y = 1 To sq_d_2 |
|||
For x = 1 To l |
|||
Swap sq(x, y), sq(x,y + sq_d_2) |
|||
Next |
|||
Next |
|||
' make indent |
|||
y = (sq_d_2 \ 2) +1 |
|||
Swap sq(1, y), sq(1, y + sq_d_2) ' was swapped, restore to orignal value |
|||
Swap sq(l +1, y), sq(l +1, y + sq_d_2) |
|||
' swap right side |
|||
For y = 1 To sq_d_2 |
|||
For x = n - l +2 To n |
|||
Swap sq(x, y), sq(x,y + sq_d_2) |
|||
Next |
|||
Next |
|||
' check columms and rows |
|||
For y = 1 To n |
|||
nr = 0 : l = 0 |
|||
For x = 1 To n |
|||
nr += sq(x,y) |
|||
l += sq(y,x) |
|||
Next |
|||
If nr <> magic_sum Or l <> magic_sum Then |
|||
Err_msg "Error: value <> magic_sum" |
|||
Exit Sub |
|||
End If |
|||
Next |
|||
' check diagonals |
|||
nr = 0 : l = 0 |
|||
For x = 1 To n |
|||
nr += sq(x, x) |
|||
l += sq(n - x +1, n - x +1) |
|||
Next |
|||
If nr <> magic_sum Or l <> magic_sum Then |
|||
Err_msg "Error: value <> magic_sum" |
|||
Exit Sub |
|||
End If |
|||
' printing square's on screen bigger when |
|||
' n > 19 results in a wrapping of the line |
|||
Print "Single even magic square size: "; n; "*"; n |
|||
Print "The magic sum = "; magic_sum |
|||
Print |
|||
For y = 1 To n |
|||
For x = 1 To n |
|||
Print Using frmt; sq(x, y); |
|||
Next |
|||
Print |
|||
Next |
|||
' output magic square to a file with the name provided |
|||
If filename <> "" Then |
|||
nr = FreeFile |
|||
Open filename For Output As #nr |
|||
Print #nr, "Single even magic square size: "; n; "*"; n |
|||
Print #nr, "The magic sum = "; magic_sum |
|||
Print #nr, |
|||
For y = 1 To n |
|||
For x = 1 To n |
|||
Print #nr, Using frmt; sq(x,y); |
|||
Next |
|||
Print #nr, |
|||
Next |
|||
Close #nr |
|||
End If |
|||
End Sub |
|||
' ------=< MAIN >=------ |
|||
se_magicsq(6, "magicse6.txt") : Print |
|||
' empty keyboard buffer |
|||
While Inkey <> "" : Var _key_ = Inkey : Wend |
|||
Print : Print "hit any key to end program" |
|||
Sleep |
|||
End</lang> |
|||
{{out}} |
|||
<pre>Single even magic square size: 6*6 |
|||
The magic sum = 111 |
|||
35 1 6 26 19 24 |
|||
3 32 7 21 23 25 |
|||
31 9 2 22 27 20 |
|||
8 28 33 17 10 15 |
|||
30 5 34 12 14 16 |
|||
4 36 29 13 18 11</pre> |
|||
=={{header|Java}}== |
=={{header|Java}}== |
||
<lang java>public class MagicSquareSinglyEven { |
<lang java>public class MagicSquareSinglyEven { |
Revision as of 15:39, 18 March 2016
A magic square of singly even order has a size that is a multiple of 4, plus 2 (e.g. 6, 10, 14). This means that the subsquares have an odd size, which plays a role in the construction.
The task: create a magic square of 6 x 6.
- Cf.
- See also
FreeBASIC
<lang freebasic>' version 18-03-2016 ' compile with: fbc -s console ' singly even magic square 6, 10, 14, 18...
Sub Err_msg(msg As String)
Print msg Beep : Sleep 5000, 1 : Exit Sub
End Sub
Sub se_magicsq(n As UInteger, filename As String = "")
' filename <> "" then save square in a file ' filename can contain directory name ' if filename exist it will be overwriten, no error checking
If n < 6 Then Err_msg( "Error: n is to small") Exit Sub End If
If ((n -2) Mod 4) <> 0 Then Err_msg "Error: not possible to make singly" + _ " even magic square size " + Str(n) Exit Sub End If
Dim As UInteger sq(1 To n, 1 To n) Dim As UInteger magic_sum = n * (n ^ 2 +1) \ 2 Dim As UInteger sq_d_2 = n \ 2, q2 = sq_d_2 ^ 2 Dim As UInteger l = (n -2) \ 4 Dim As UInteger x = sq_d_2 \ 2 + 1, y = 1, nr = 1 Dim As String frmt = String(Len(Str(n * n)) +1, "#")
' fill pattern A C ' D B ' main loop for creating magic square in section A ' the value for B,C and D is derived from A ' uses the FreeBASIC odd order magic square routine Do If sq(x, y) = 0 Then sq(x , y ) = nr ' A sq(x + sq_d_2, y + sq_d_2) = nr + q2 ' B sq(x + sq_d_2, y ) = nr + q2 * 2 ' C sq(x , y + sq_d_2) = nr + q2 * 3 ' D If nr Mod sq_d_2 = 0 Then y += 1 Else x += 1 : y -= 1 End If nr += 1 End If If x > sq_d_2 Then x = 1 Do While sq(x,y) <> 0 x += 1 Loop End If If y < 1 Then y = sq_d_2 Do While sq(x,y) <> 0 y -= 1 Loop End If Loop Until nr > q2
' swap left side For y = 1 To sq_d_2 For x = 1 To l Swap sq(x, y), sq(x,y + sq_d_2) Next Next ' make indent y = (sq_d_2 \ 2) +1 Swap sq(1, y), sq(1, y + sq_d_2) ' was swapped, restore to orignal value Swap sq(l +1, y), sq(l +1, y + sq_d_2)
' swap right side For y = 1 To sq_d_2 For x = n - l +2 To n Swap sq(x, y), sq(x,y + sq_d_2) Next Next
' check columms and rows For y = 1 To n nr = 0 : l = 0 For x = 1 To n nr += sq(x,y) l += sq(y,x) Next If nr <> magic_sum Or l <> magic_sum Then Err_msg "Error: value <> magic_sum" Exit Sub End If Next
' check diagonals nr = 0 : l = 0 For x = 1 To n nr += sq(x, x) l += sq(n - x +1, n - x +1) Next If nr <> magic_sum Or l <> magic_sum Then Err_msg "Error: value <> magic_sum" Exit Sub End If ' printing square's on screen bigger when ' n > 19 results in a wrapping of the line Print "Single even magic square size: "; n; "*"; n Print "The magic sum = "; magic_sum Print For y = 1 To n For x = 1 To n Print Using frmt; sq(x, y); Next Print Next
' output magic square to a file with the name provided If filename <> "" Then nr = FreeFile Open filename For Output As #nr Print #nr, "Single even magic square size: "; n; "*"; n Print #nr, "The magic sum = "; magic_sum Print #nr, For y = 1 To n For x = 1 To n Print #nr, Using frmt; sq(x,y); Next Print #nr, Next Close #nr End If
End Sub
' ------=< MAIN >=------
se_magicsq(6, "magicse6.txt") : Print
' empty keyboard buffer While Inkey <> "" : Var _key_ = Inkey : Wend Print : Print "hit any key to end program" Sleep End</lang>
- Output:
Single even magic square size: 6*6 The magic sum = 111 35 1 6 26 19 24 3 32 7 21 23 25 31 9 2 22 27 20 8 28 33 17 10 15 30 5 34 12 14 16 4 36 29 13 18 11
Java
<lang java>public class MagicSquareSinglyEven {
public static void main(String[] args) { int n = 6; for (int[] row : magicSquareSinglyEven(n)) { for (int x : row) System.out.printf("%2s ", x); System.out.println(); } System.out.printf("\nMagic constant: %d ", (n * n + 1) * n / 2); }
public static int[][] magicSquareOdd(final int n) { if (n < 3 || n % 2 == 0) throw new IllegalArgumentException("base must be odd and > 2");
int value = 0; int gridSize = n * n; int c = n / 2, r = 0;
int[][] result = new int[n][n];
while (++value <= gridSize) { result[r][c] = value; if (r == 0) { if (c == n - 1) { r++; } else { r = n - 1; c++; } } else if (c == n - 1) { r--; c = 0; } else if (result[r - 1][c + 1] == 0) { r--; c++; } else { r++; } } return result; }
static int[][] magicSquareSinglyEven(final int n) { if (n < 6 || (n - 2) % 4 != 0) throw new IllegalArgumentException("base must be a positive " + "multiple of 4 plus 2");
int size = n * n; int halfN = n / 2; int subSquareSize = size / 4;
int[][] subSquare = magicSquareOdd(halfN); int[] quadrantFactors = {0, 2, 3, 1}; int[][] result = new int[n][n];
for (int r = 0; r < n; r++) { for (int c = 0; c < n; c++) { int quadrant = (r / halfN) * 2 + (c / halfN); result[r][c] = subSquare[r % halfN][c % halfN]; result[r][c] += quadrantFactors[quadrant] * subSquareSize; } }
int nColsLeft = halfN / 2; int nColsRight = nColsLeft - 1;
for (int r = 0; r < halfN; r++) for (int c = 0; c < n; c++) { if (c < nColsLeft || c >= n - nColsRight || (c == nColsLeft && r == nColsLeft)) {
if (c == 0 && r == nColsLeft) continue;
int tmp = result[r][c]; result[r][c] = result[r + halfN][c]; result[r + halfN][c] = tmp; } }
return result; }
}</lang>
35 1 6 26 19 24 3 32 7 21 23 25 31 9 2 22 27 20 8 28 33 17 10 15 30 5 34 12 14 16 4 36 29 13 18 11 Magic constant: 111
Perl 6
See Magic squares/Perl 6 for a general magic square generator. Note that it produces a magic square, not the magic square. The output is different each time.
- Output:
With a parameter of 6:
26 35 1 19 6 24 17 8 28 10 33 15 12 30 5 14 34 16 13 4 36 18 29 11 21 3 32 23 7 25 22 31 9 27 2 20 The magic number is 111
With a parameter of 10:
78 46 37 44 53 94 96 35 12 10 97 45 31 38 72 13 95 29 6 79 22 70 56 63 47 88 20 54 81 4 90 33 49 26 65 76 83 42 24 17 84 27 43 50 59 100 77 36 18 11 9 52 68 75 34 25 2 61 93 86 91 39 30 32 66 82 89 48 5 23 16 64 55 57 41 7 14 73 80 98 15 58 74 51 40 1 8 67 99 92 3 71 62 69 28 19 21 60 87 85 The magic number is 505
zkl
<lang zkl>class MagicSquareSinglyEven{
fcn init(n){ var result=magicSquareSinglyEven(n) } fcn toString{ sink,n:=Sink(String),result.len(); // num collumns fmt:="%2s "; foreach row in (result) { sink.write(row.apply('wrap(n){ fmt.fmt(n) }).concat(),"\n") } sink.write("\nMagic constant: %d".fmt((n*n + 1)*n/2)); sink.close(); } fcn magicSquareOdd(n){ if (n<3 or n%2==0) throw(Exception.ValueError("base must be odd and > 2")); value,gridSize,c,r:=0, n*n, n/2, 0; result:=n.pump(List(),n.pump(List(),0).copy); // array[n,n] of zero while((value+=1)<=gridSize){
result[r][c]=value; if(r==0){ if(c==n-1) r+=1;
else{ r=n-1; c+=1; }
} else if(c==n-1){ r-=1; c=0; } else if(result[r-1][c+1]==0){ r-=1; c+=1; } else r+=1;
} result; } fcn magicSquareSinglyEven(n){ if (n<6 or (n-2)%4!=0)
throw(Exception.ValueError("base must be a positive multiple of 4 +2"));
size,halfN,subSquareSize:=n*n, n/2, size/4;
subSquare:=magicSquareOdd(halfN); quadrantFactors:=T(0, 2, 3, 1); result:=n.pump(List(),n.pump(List(),0).copy); // array[n,n] of zero
foreach r,c in (n,n){ quadrant:=(r/halfN)*2 + (c/halfN);
result[r][c]=subSquare[r%halfN][c%halfN]; result[r][c]+=quadrantFactors[quadrant]*subSquareSize;
} nColsLeft,nColsRight:=halfN/2, nColsLeft-1; foreach r,c in (halfN,n){ if ( c<nColsLeft or c>=(n-nColsRight) or (c==nColsLeft and r==nColsLeft) ){
if(c==0 and r==nColsLeft) continue; tmp:=result[r][c]; result[r][c]=result[r+halfN][c]; result[r+halfN][c]=tmp; }
} result }
}</lang> <lang zkl>MagicSquareSinglyEven(6).println();</lang>
- Output:
35 1 6 26 19 24 3 32 7 21 23 25 31 9 2 22 27 20 8 28 33 17 10 15 30 5 34 12 14 16 4 36 29 13 18 11 Magic constant: 111