Dieser Code gibt dir aus, ob eine Zahl gerade ist, ob fibo, ob prim, ob zwillingsprim.
Da du sicher keine function istprim(zahl) verwenden darfst, merken wir uns halt in zwei booleschen Variablen, ob die letzte ungerade Zahl (zahl-2) prim war (letzte_warprim) und ob die nächste ungerade (zahl+2) es sein wird (naechste_istprim). So müssen wir jede zahl nur einmal auf prim prüfen.
Die "Spezialwerte" 0,1,2 geben wir direkt aus. (Man müsste den Code durch diese drei "Sonderfälle" aufblähen. - Tun wir nicht.)
Was macht das Programm?
Fibo: Für fibo berechnen wir am Anfang die kleinste Fibo-Zahl f, welche >= LOWER_BORDER ist. Dann geht's ab in die while Schleife. Sobald zahl=f wissen wir "fibo!". Wir setzen im fibo Fall istfibo:=TRUE und müssen das nächste Glied f der Fibofolge berechnen. Bei der Berechnung von f=f[n] greifen wir auf die gespeicherten Werte von f[n-1] und f[n-2] zurück.
Gerade: istgerade := zahl mod 2 = 0; und das war's bereits.
Primzahlen und deren Zwillinge: Für Zahlen, welche ungerade sind, prüfen wir auf prim. Wir prüfen dabei nicht die aktuelle Zahl, sondern "zahl+2". Grund: Wir müssen für die Bewertung "zahl ist Zwilling oder nicht" wissen, ob die nächste ungerade Zahl "zahl+2" prim ist. Wir speichern in naechste_istprim ab, ob "zahl+2" prim ist. In letzte_warprim merken wir uns, ob die letzte ungerade Zahl prim war. In diese_istprim steht, ob zahl prim ist. diese_istprim berechnen wir dabei nicht via Faktorzerlegung von zahl: Wir wissen ja dank letzte_warprim, ob zahl prim ist oder nicht. "zahl" ist Teil eines Primzahlzwillings, wenn
primzwilling := diese_istprim and ( letzte_warprim or naechste_istprim );
Fertig - Viel Spass beim Denken.
Delphi-Quellcode:
var teiler, sqrt_n, naechste, zahl, fn_1, fn_2, f : int64;
primzwilling, istfibo, istgerade, letzte_warprim, naechste_istprim, diese_istprim : boolean;
const
LOWER_BORDER = 0;
UPPER_BORDER = 50;
begin
if ( LOWER_BORDER = 0 ) then writeln( '0 even: TRUE fib: TRUE prim: FALSE twinprim: FALSE' );
if ( LOWER_BORDER <= 1 ) and ( 1 <= UPPER_BORDER ) then writeln( '1 even: FALSE fib: TRUE prim: FALSE twinprim: FALSE' );
if ( LOWER_BORDER <= 2 ) and ( 2 <= UPPER_BORDER ) then writeln( '2 even: TRUE fib: TRUE prim: FALSE twinprim: FALSE' );
if ( LOWER_BORDER mod 2 = 0 ) then zahl := LOWER_BORDER-3 else zahl := LOWER_BORDER-4;
if ( zahl < 3 ) then
begin
zahl := 3;
naechste_istprim := true; // 3 ist Primzahl
end;
fn_1 := 1;
fn_2 := 1;
f := 2;
while ( f < zahl ) do // berechne die kleinste Fibo-Zahl f, welche >= LOWER_BORDER
begin
f := fn_1 + fn_2;
fn_2 := fn_1;
fn_1 := f;
end;
while ( zahl <= UPPER_BORDER ) do
begin
istfibo := f = zahl;
if istfibo then
begin // die nächste Fibozahl wird berechnet
f := fn_1 + fn_2;
fn_2 := fn_1;
fn_1 := f;
end;
istgerade := zahl mod 2 = 0;
if not istgerade then
begin
diese_istprim := naechste_istprim; // in durchlauf "zahl-2" haben wir berechnet, ob "zahl" prim ist
naechste := zahl + 2; // die nächste ungerade zahl nach "zahl" auf prim prüfen
sqrt_n := trunc(sqrt(naechste)); // bis zu diesem wert suchen wir nach möglichen teilern von naechste
teiler := 3;
naechste_istprim := true; // wir nehmen mal an, "naechste" sei prim
while naechste_istprim and ( teiler <= sqrt_n ) do
begin // und prüfen, ob dem so ist
naechste_istprim := naechste mod teiler <> 0;
inc( teiler, 2 );
end;
// naechste_istprim = true, wenn naechste=zahl+2 prim ist
// wir prüfen, ob "zahl" zu einem Zwilling gehört
primzwilling := diese_istprim and ( letzte_warprim or naechste_istprim );
letzte_warprim := diese_istprim; // wir merken uns für runde "zahl+2", ob "zahl" prim ist
end
else
begin
diese_istprim := false; // "zahl" ist gerade also nicht prim
primzwilling := false; // ..und damit auch nicht Teil eines Zwillings
end;
if ( zahl >= LOWER_BORDER ) then // Ausgabe
writeln(zahl, ' even: ', istgerade, ' fib: ', istfibo, ' prim: ', diese_istprim, ' twinprim: ', primzwilling );
inc( zahl );
end;
readln;