Einzelnen Beitrag anzeigen

Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
719 Beiträge
 
Delphi 11 Alexandria
 
#24

AW: Erstellung einer Schleife mit drei Überprüfungen

  Alt 24. Mai 2021, 21:22
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;
Michael Gasser

Geändert von Michael II (24. Mai 2021 um 22:06 Uhr)
  Mit Zitat antworten Zitat