home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
Modula
/
Source
/
Magic.MOD
< prev
next >
Wrap
Text File
|
1985-05-11
|
5KB
|
194 lines
MODULE MagischePrimzahlenQuadrate;
(* Marcello Merkle , 18.4.85 *)
(* Dieses Programm berechnet alle moeglichen Magischen-Primzahlen-Quadrate
(3*3)bis zu einer vorgegebener Primzahl. Loesungen die Spiegel- oder
Rotationssymmetrisch sind werden dabei nicht angegeben.
Bsp:
17 89 71 Dies ist die kleinste Loesung.
113 59 5 Ihre Zeilen-/Kolonnen-/Diagonalensumme betraegt
47 29 101 177.
Es wurde im Rahmen des VISionen Wettbewerb (Feb. 85) geschrieben.
*)
FROM Terminal IMPORT
Write, WriteString, WriteLn, Read, ReadString, ClearTerminal, BusyRead;
FROM InTerminal IMPORT
ReadI;
FROM Conversions IMPORT
ConvertInteger;
FROM M2Files IMPORT
File, eolc, Create, Close, WriteChar, SetTypeandCreator;
FROM OutFile IMPORT FWriteI, FWriteT, FWriteLn;
CONST
maxim = 5000; (* maxim erhoehen fuer noch mehr Loesungen *)
maxi = (maxim-1) DIV 2; (* das Erathostenessieb ist ohne geraden Zahlen *)
sf = 15; (* Sicherheitsfaktor*2 >= MAX{1<=i<π(maxim)}(Prim[i]-Prim[i+1]) *)
ESC = 33c;
VAR
sieb : ARRAY[-sf..maxi+sf] OF BOOLEAN;
x,a,b,c,d, max,
anzLoes, viceC : INTEGER;
ch : CHAR;
toFile,done,
quitFlag : BOOLEAN;
fname : ARRAY[0..30] OF CHAR;
str : ARRAY[0..99] OF CHAR;
FType, FCreator: ARRAY[0..3] OF CHAR;
f : File;
PROCEDURE Erathostenes;
VAR
i,j,k : INTEGER;
BEGIN
FOR i:= -sf TO maxi+sf DO sieb[i]:= TRUE; END;
i:= 1; j:= 3; k:= 4;
REPEAT
REPEAT
sieb[k]:= FALSE; INC(k,j)
UNTIL k>maxi;
REPEAT INC(i) UNTIL sieb[i];
k:= 2*i*(i+1); j:= 2*i+1;
UNTIL k>maxi
END Erathostenes;
PROCEDURE Suche(VAR offset:INTEGER);
BEGIN
REPEAT
INC(offset)
UNTIL sieb[x+offset] AND sieb[x-offset]
END Suche;
PROCEDURE Overflow(offset:INTEGER): BOOLEAN;
BEGIN
RETURN (x+offset > max) OR (x-offset <= 1);
END Overflow;
PROCEDURE SymPrim(offset:INTEGER):BOOLEAN;
BEGIN
RETURN sieb[x+offset] AND sieb[x-offset];
END SymPrim;
PROCEDURE WriteInt(i,len:INTEGER);
VAR str: ARRAY [0..6] OF CHAR;
BEGIN
ConvertInteger(i,len,str);
WriteString(str);
END WriteInt;
PROCEDURE Print(x,a,b,c,d: INTEGER);
VAR str: ARRAY [0..20] OF CHAR;
BEGIN
x:= 2*x+1;
a:= 2*a; b:= 2*b; c:= 2*c; d:= 2*d;
INC(anzLoes);WriteInt(anzLoes,3);
WriteString(". Loesung: ");
WriteInt(3*x,5); WriteLn;
WriteInt(x-a,5); WriteInt(x+d,5); WriteInt(x+c,5); WriteLn;
WriteInt(x+b,5); WriteInt(x ,5); WriteInt(x-b,5); WriteLn;
WriteInt(x-c,5); WriteInt(x-d,5); WriteInt(x+a,5); WriteLn;
WriteLn;
IF toFile THEN
FWriteI(f, anzLoes,3); str:= ". Loesung: ";
FWriteT(f, str,11);
FWriteI(f, 3*x,5); FWriteLn(f);
FWriteI(f, x-a,5); FWriteI(f, x+d,5); FWriteI(f, x+c,5); FWriteLn(f);
FWriteI(f, x+b,5); FWriteI(f, x ,5); FWriteI(f, x-b,5); FWriteLn(f);
FWriteI(f, x-c,5); FWriteI(f, x-d,5); FWriteI(f, x+a,5); FWriteLn(f);
FWriteLn(f);
END;
IF NOT(toFile) AND (anzLoes MOD 5 = 0) THEN
WriteString("...");
Read(ch); WriteLn; ClearTerminal;
ELSE BusyRead(ch);
END;
IF ch=ESC THEN quitFlag:= TRUE; END;
END Print;
BEGIN (*MagischePrimzahlenQuadrate*)
REPEAT
anzLoes:= 0; quitFlag:= FALSE;
WriteString
("++++++++++++++ Alle Magischen Primzahlenquadrate 3*3 ++++++++++++++mam85");
WriteLn; WriteLn;
WriteString("Bis zu welcher Primzahl (nicht groesser als ");
WriteInt(maxim,4); WriteString(", exit=0) : ? ");
ReadI(max);
WHILE (max<0) OR (max>maxim) DO ReadI(max); END;
max:= (max-1) DIV 2; WriteLn;
WriteString("Loesungen auf Terminal ofer File (t/f): ");
Read(ch); WriteLn;
IF (ch = 'f') OR (ch = 'F') THEN
toFile:= TRUE ELSE toFile:= FALSE
END;
IF toFile THEN
WriteLn;
WriteString("Gib einen Namen fuer das File an :");
ReadString(fname); WriteLn;
Create(f,fname,done);
IF NOT done THEN
WriteString("Nicht geoeffnet, normaler Terminaloutput.");
toFile:= FALSE;
ELSE
str:= "+++ Alle Magischen Primzahlenquadrate bis";
FWriteT(f,str,41);
ConvertInteger(2*(max+1),5,str);
FWriteT(f,str,5);
str:= " +++";
FWriteT(f,str,4);
FWriteLn(f); FWriteLn(f);
END;
ELSE
ClearTerminal;
END;
Erathostenes;
x:= 59 DIV 2;(* erste Loesung *)
REPEAT
c:= 0;
Suche(c);
REPEAT
d:= c;
Suche(d); viceC:= d;
LOOP
a:= c+d;
b:= a+c;
IF Overflow(b) THEN EXIT END;
IF SymPrim(a) THEN
IF SymPrim(b) THEN Print(x,a,b,c,d) END;
b:= a+d;
IF NOT(Overflow(b)) AND SymPrim(b) THEN
Print(x,a,b,d,c);
IF quitFlag THEN EXIT; END
END;
END;
Suche(d);
END;(*LOOP*)
c:= viceC;
UNTIL (c=d) OR quitFlag;
REPEAT INC(x) UNTIL sieb[x];
UNTIL (x>max) OR quitFlag;
IF toFile THEN
IF quitFlag THEN
FWriteLn(f);
str:= "mit ESC abgebrochen...";
FWriteT(f, str, 22); FWriteLn(f);
END;
FType:= "TEXT"; FCreator:= "EDIT";
SetTypeandCreator(f,FType, FCreator, done);
Close(f,done);
IF NOT done THEN WriteString('ERROR: File not closed'); END;
END;
WriteString("Das war's."); WriteLn;
WriteString("..."); Read(ch); ClearTerminal;
UNTIL max=0;
END MagischePrimzahlenQuadrate.(c)MaM85