home *** CD-ROM | disk | FTP | other *** search
- 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