PDA

View Full Version : Magic square finder



Foundry
04-18-2014, 05:35 AM
Just learned about "magic squares" in my calculus class today. Decided to make a script that can test and find magic squares. This is a very basic brute force way of finding them that just creates random squares until one works. Hope somebody can learn from this or something :D

program magicSquareMaker;

type
TSquare = array of TIntegerArray;

function TIntegerArray.add(): Integer;
var
i: Integer;
begin
for i to high(self) do
result := result + self[i];
end;

function getRandomNumber(size: Integer; var exceptions: TIntegerArray): Integer;
var
i: Integer;
begin
repeat
result := random(size) + 1;
for i := 0 to high(exceptions) do
begin
if exceptions[i] = 0 then
exit;
if result = exceptions[i] then
continue(2);
end;
exit;
until(false);
end;

function getRNRSequence(size: Integer): TIntegerArray;
var
i: Integer;
used: TIntegerArray;
begin
setLength(result, size);
setLength(used, size);
for i := 0 to high(result) do
begin
result[i] := getRandomNumber(size, used);
used[i] := result[i];
end;
end;

procedure TSquare.setup(size: Integer);
var
i: Integer;
begin
setLength(self, size);
for i to size - 1 do
setLength(self[i], size);
end;

procedure TSquare.print();
var
i: Integer;
begin
for i to high(self) do
writeLn(self[i]);
end;

procedure TSquare.populate();
var
i, j, k, l: Integer;
numbers: TIntegerArray;
begin
l := length(self);
numbers := getRNRSequence(l * l);
for i to l - 1 do
begin
for j := 0 to l - 1 do
begin
self[i][j] := numbers[k];
inc(k);
end;
end;
end;

function TSquare.isHorizontal(): Boolean;
var
i, prevsum, cursum: Integer;
begin
for i to high(self) do
begin
cursum := self[i].add();
if (cursum <> prevsum) and
(prevsum <> 0) then
exit
else
prevsum := cursum;
end;
result := true;
end;

function TSquare.isVertical(): Boolean;
var
i, j, h, prevsum, cursum: Integer;
begin
h := high(self);
for i to h do
begin
cursum := 0;
for j := 0 to h do
cursum := cursum + self[j][i];
if (cursum <> prevsum) and
(prevsum <> 0) then
exit
else
prevsum := cursum;
end;
result := true;
end;

function TSquare.isDiagonal(): Boolean;
var
i, h, LToRight, RToLeft: Integer;
begin
h := high(self);
for i to h do
LToRight := LToRight + self[i][i];
for i := h downto 0 do
RToLeft := RToLeft + self[i][h - i];
result := (LToRight = RToLeft);
end;

var
special: TSquare;

begin
special.setup(3);
repeat
special.populate();
until(special.isVertical() and special.isHorizontal() and special.isDiagonal());
special.print();
end.

An example of what a magic square is:


Compiled successfully in 922 ms.
[8, 3, 4] Basically all of the horizontal, vertical, and diagonal rows add to the same number.
[1, 5, 9]
[6, 7, 2]
Successfully executed.

smp2031
05-06-2014, 01:39 AM
What is this used for???

Foundry
05-06-2014, 01:50 AM
What is this used for???

Something I wrote on a whim... really no use for them although they have had some philosophical interest in the past. Actually after looking at the Wikipedia page I may attempt to make a better one that actually "constructs" the square as opposed to just solving random ones.