Если знаете паскаль. И собираетесь писать на фри паскале/Delphi.
Увы! Сейчас не знаю. Очень давно, когда работала, Паскаль знала и писала на нём программы.
Теперь, после многолетнего перерыва, знаю только Бейсик
(см. самую перву цитату)
Пишу на QBASIC. Коллега svb нашёл для меня очень хороший компилятор pb5 (до того работала с интерпретатором).
Написала под этот компилятор десятки программ построения разных магических квадратов, ничего, нормально строятся квадраты
Сейчас меня интересует такой вопрос. Вот есть готовый код программы построения пандиагонального квадрата 6-го порядка, я дала ссылку на страницу, где автор выложил исходники, там так и написано "Исходники. Windows/Delphi". Как я понимаю, программа написана на Delphi.
Вот код программы (если я правильно поняла):
(Оффтоп)
unit uCommon;
interface
// Используемые типы данных
const mx = 43;
type
PNumbers = ^TNumbers;
TNumbers = array [0..mx*mx-1] of int64;
TMatrix = array [0..mx-1, 0..mx-1] of int64;
type
TAInteger = array of integer;
procedure ViewSquare(k:integer; ms:TMatrix; S:int64; p:boolean=false; a:boolean=false); overload;
procedure ViewSquare(var F:TextFile; k:integer; ms:TMatrix; S:int64; p:boolean=false; a:boolean=false); overload;
procedure ViewNumbers(k:integer; S:int64; A:TNumbers);
procedure ViewMatrix(k:integer; A:TNumbers);
function GetCnk(n, k:integer):int64;
procedure SetA(var A:TNumbers; b:array of int64);
procedure SetM(n:integer; var M:TMatrix; b:array of int64); overload;
procedure SetM(n:integer; var M:TMatrix; b:array of integer); overload;
function toMatrix(n:integer; A:TNumbers):TMatrix;
function CheckMS(n:integer; m:TMatrix; var S:int64; var p, a:boolean):boolean;
procedure ToMatrixRosser(n:integer; A:TNumbers; var M:TMatrix);
function isMagic(n:integer; M:TMatrix; var S:int64; var p:boolean):boolean;
function isPMagic(n:integer; M:TMatrix; S:int64):boolean;
procedure RosserToMatrix(n:integer; M:TMatrix; var A:TNumbers);
function isDifferent(n:integer; M:TMatrix):boolean;
procedure SetAInteger(a:array of integer; var ls:TAInteger);
implementation
procedure SetA(var A:TNumbers; b:array of int64);
var i:integer;
begin
fillchar(A, sizeof(A), 0);
for i := low(b) to high(b) do begin
A[i] := b[i];
end;
end;
procedure ViewSquare(k:integer; ms:TMatrix; S:int64; p:boolean=false; a:boolean=false);
var i, j : integer;
begin
write(k, ':[');
if p then write('p');
if a then write('a');
write(']:', S, ': ');
for i := 0 to k-1 do
for j := 0 to k-1 do begin
write(ms[i, j]);
if (i < k-1) or (j < k-1) then write(',');
end;
writeln;
end;
procedure ViewSquare(var F:TextFile; k:integer; ms:TMatrix; S:int64; p:boolean=false; a:boolean=false);
var i, j : integer;
begin
write(F, k, ':[');
if p then write(F, 'p');
if a then write(F, 'a');
write(F, ']:', S, ': ');
for i := 0 to k-1 do
for j := 0 to k-1 do begin
write(F, ms[i, j]);
if (i < k-1) or (j < k-1) then write(F, ',');
end;
writeln(F);
end;
procedure ViewNumbers(k:integer; S:int64; A:TNumbers);
var i : integer;
begin
write(k, ':');
write(S, ': ');
for i := 0 to k-1 do begin
write(A[i]);
if (i < k-1) then write(',');
end;
writeln;
end;
// Возвращает количество сочетаний из n по k
// (без учета порядка следования)
// Cnk = n!/(k!*(n-k)!)
function GetCnk(n, k:integer):int64;
var d:integer;
begin
d := n-k;
result := 1;
while n > d do begin
result := result * n;
dec(n);
end;
while k > 1 do begin
result := result div k;
dec(k);
end;
end;
function toMatrix(n:integer; A:TNumbers):TMatrix;
var i, j:integer;
begin
fillchar(result, sizeof(result), 0);
for i := 0 to n-1 do begin
for j := 0 to n-1 do begin
result[i, j] := A[i*n+j];
end;
end;
end;
// Проверка MS
function CheckMS(n:integer; m:TMatrix; var S:int64; var p, a:boolean):boolean;
var i, j, l1, l2 : integer;
S1:integer;
K:int64;
begin
p := false;
result := true;
// Считаем константу
S := 0;
for j := 0 to n-1 do S := S + m[0, j];
// Проверка по строкам
for i := 0 to n-1 do begin
S1 := 0;
for j := 0 to n-1 do S1 := S1 + m[i, j];
if S1 <> S then begin
result := false;
exit;
end;
end;
// Проверка по столбцам
for i := 0 to n-1 do begin
S1 := 0;
for j := 0 to n-1 do S1 := S1 + m[j, i];
if S1 <> S then begin
result := false;
exit;
end;
end;
// Проверка двух диагоналей
S1 := 0;
for j := 0 to n-1 do S1 := S1 + m[j,j];
if S1 <> S then begin
result := false;
exit;
end;
S1 := 0;
for j := 0 to n-1 do S1 := S1 + m[j,n-1-j];
if S1 <> S then begin
result := false;
exit;
end;
// Проверка пандиагональности
p := true;
for j := {0}1 to n-1 do begin
S1 := 0;
for i := 0 to n-1 do S1 := S1 + m[i,(j+i) mod n];
if S1 <> S then begin
p := false;
break;
end;
end;
if p then begin
for j := n{k-1} to 2*n-1 do begin
S1 := 0;
for i := 0 to n-1 do S1 := S1 + m[i,(j-i) mod n];
if S1 <> S then begin
p := false;
break;
end;
end;
end;
// Проверка ассоциативности
K := m[0,0] + m[n-1,n-1];
a := true;
l1 := (n-1) div 2;
for i := 0 to l1 do begin
l2 := (n-1) div 2;
if n mod 2 <> 0 then dec(l2);
for j := 0 to l2 do begin
S1 := m[i,j] + m[n-1-i,n-1-j];
if S1 <> K then begin
a := false;
break;
end;
end;
end;
end;
function isMagic(n:integer; M:TMatrix; var S:int64; var p:boolean):boolean;
var i,j:integer;
S1:int64;
begin
result := false;
// Вычисление суммы
S := 0;
for i := 0 to n-1 do S := S + M[0, i];
// Проверка строк
for i := 0 to n-1 do begin
S1 := 0;
for j := 0 to n-1 do begin
S1 := S1 + M[i, j];
end;
if S1 <> S then exit;
end;
// Проверка столбцов
for i := 0 to n-1 do begin
S1 := 0;
for j := 0 to n-1 do begin
S1 := S1 + M[j, i];
end;
if S1 <> S then exit;
end;
// Проверка двух диагоналей
S1 := 0;
for j := 0 to n-1 do begin
S1 := S1 + M[j, j];
end;
if S1 <> S then exit;
S1 := 0;
for j := 0 to n-1 do begin
S1 := S1 + M[j, n-1-j];
end;
if S1 <> S then exit;
result := true;
p := isPMagic(n, M, S);
end;
function isPMagic(n:integer; M:TMatrix; S:int64):boolean;
var k, i:integer;
S1 : int64;
begin
result := false;
for k := 0 to n-1 do begin
S1 := 0;
for i := 0 to n-1 do begin
S1 := S1 + M[i, (k+i) mod n];
end;
if S1 <> S then exit;
end;
for k := n to 2*n-1 do begin
S1 := 0;
for i := 0 to n-1 do begin
S1 := S1 + M[i, (k-i) mod n];
end;
if S1 <> S then exit;
end;
result := true;
end;
procedure ToMatrixRosser(n:integer; A:TNumbers; var M:TMatrix);
var i, j, k, l : integer;
begin
for i := 0 to n-1 do begin
for j := 0 to n-1 do begin
k := (3*i+2*j) mod n;
l := (2*i+j) mod n;
M[k,l] := A[i*n+j];
end;
end;
end;
procedure RosserToMatrix(n:integer; M:TMatrix; var A:TNumbers);
var i, j, k, l : integer;
begin
for i := 0 to n-1 do begin
for j := 0 to n-1 do begin
k := (3*i+2*j) mod n;
l := (2*i+j) mod n;
A[i*n+j] := M[k,l];
end;
end;
end;
procedure SetM(n:integer; var M:TMatrix; b:array of int64);
var i, j:integer;
begin
for i := 0 to n-1 do
for j := 0 to n-1 do begin
M[i,j] := b[i*n+j];
end;
end;
procedure SetM(n:integer; var M:TMatrix; b:array of integer);
var i, j:integer;
begin
for i := 0 to n-1 do
for j := 0 to n-1 do begin
M[i,j] := b[i*n+j];
end;
end;
procedure ViewMatrix(k:integer; A:TNumbers);
var i, j:integer;
begin
for i := 0 to k-1 do begin
for j := 0 to k-1 do begin
write(A[i*k+j], ' ');
end;
writeln;
end;
end;
// Проверка всех чисел матрицы
// возвращает true, если все числа различны
function isDifferent(n:integer; M:TMatrix):boolean;
var i, j, k, l, c:integer;
D:int64;
begin
result := true;
for i := 0 to n-1 do begin
for j := 0 to n-1 do begin
D := m[i, j]; c := 0;
for k := 0 to n-1 do begin
for l := 0 to n-1 do begin
if m[k, l] = D then begin
inc(c);
if c > 1 then begin
writeln(D);
result := false;
exit;
end;
end;
end;
end;
end;
end;
end;
// a -> ls
procedure SetAInteger(a:array of integer; var ls:TAInteger);
var i:integer;
begin
SetLength(ls, high(a)-low(a)+1);
for i := 0 to length(ls) - 1 do ls[i] := a[i];
end;
end.
Программа эта замечательно работает, написана она очень грамотным программистом (автор alexBlack). Беда в том, что работает она очень долго, для некоторых магических констант проверка может занимать несколько суток.
В этой программе не задействована многоядерность процессора.
Вопрос следующий: возможно ли и насколько сложно ввести в эту программу распараллеливание всего процесса вычислений?
У меня, как уже писала, всего два ядра в процессоре. У моего коллеги svb четырёхядерный процессор. У одного товарища с другого форума восьмиядерный процессор, и он готов помочь с выполнением программы, но сам распараллелить готовый код не может.
Или, может быть, чтобы использовать многоядерность, надо писать новый код? Код, который написан для одноядерного процессора, не годится, переделать его под многоядерный процессор сложно или вообще невозможно (?)
В этом весь вопрос!