[gelöst] Zahlen in array elegant hochzählen?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1685
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

[gelöst] Zahlen in array elegant hochzählen?

Beitrag von fliegermichl »

Ich habe ein array [0..11] of integer;
Im Initialzustand hat das den Inhalt (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)

Ich möchte dessen Inhalt in einer Schleife so hochzählen wie eine Zahl, welche in jedem Digit bei 2048 überläuft.
Also erster Durchlauf alle linken Werte wie gehabt, rechtester Wert hochzählen bis 2047.

Ist dies erreicht, so soll der letzte Wert überlaufen (sprich auf 11 gesetzt) und der vorletzte von 10 auf 11 erhöht werden bis auch dieser 2047 erreicht hat.
Dann entsprechend den drittletzten erhöhen, die beiden letzten wieder auf ihre Initialwerte setzen usw.

Irgendwie fällt mir da grad keine passende Schleife für ein.
Zuletzt geändert von fliegermichl am Mo 8. Sep 2025, 11:24, insgesamt 1-mal geändert.

Warf
Beiträge: 2194
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Zahlen in array elegant hochzählen?

Beitrag von Warf »

Warum mit einem Loop und nicht mit open array und slices?

Code: Alles auswählen

function increment(var arr: array of Integer): Boolean;
begin
  Inc(arr[high(arr)]);
  if arr[high(arr)]<2048 then
    Exit(False);
  { Overflow handling }
  arr[high(arr)]:=arr[high(arr)] mod 2048;
  { wir sind beim letzten(ersten) digit, daher setzen wir result um einen overflow anzuzeigen }
  if high(arr)=low(arr) then
    Exit(True);
  { wenn wir nicht im letzten bit sind, dann schauen wir uns den array ohne das letzte feld an }
  Result:=increment(arr[low(arr)..high(arr)-1])
end;
Wenn du es aufrufst als increment(arr) dann schaut es sich zu erst den ganzen array an und inkrementiert das letzte feld. Wenn es einen overflow gab ruft es sich selbst auf aber schaut sich dabei nur bis zum vorletzten feld an, was das dann inkrementiert und so weiter und so fort.
Beim letzten(ersten) feld Angekommen kanns beim Overflow nicht mehr den array weiter gehen und gibt daher den Overflow als boolean funktionsergebnis zurück.

Wenn der FPC vernünftige Schwanzrekursionsoptimierung kann sollte das ganze auch am ende halbwegs effizient kompiliert werden

Benutzeravatar
Zvoni
Beiträge: 450
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Zahlen in array elegant hochzählen?

Beitrag von Zvoni »

Warf hat geschrieben: So 7. Sep 2025, 16:31 Warum mit einem Loop und nicht mit open array und slices?

Code: Alles auswählen

function increment(var arr: array of Integer): Boolean;
begin
  Inc(arr[high(arr)]);
  if arr[high(arr)]<2048 then
    Exit(False);
  { Overflow handling }
  arr[high(arr)]:=arr[high(arr)] mod 2048;
  { wir sind beim letzten(ersten) digit, daher setzen wir result um einen overflow anzuzeigen }
  if high(arr)=low(arr) then
    Exit(True);
  { wenn wir nicht im letzten bit sind, dann schauen wir uns den array ohne das letzte feld an }
  Result:=increment(arr[low(arr)..high(arr)-1])
end;
Wenn du es aufrufst als increment(arr) dann schaut es sich zu erst den ganzen array an und inkrementiert das letzte feld. Wenn es einen overflow gab ruft es sich selbst auf aber schaut sich dabei nur bis zum vorletzten feld an, was das dann inkrementiert und so weiter und so fort.
Beim letzten(ersten) feld Angekommen kanns beim Overflow nicht mehr den array weiter gehen und gibt daher den Overflow als boolean funktionsergebnis zurück.

Wenn der FPC vernünftige Schwanzrekursionsoptimierung kann sollte das ganze auch am ende halbwegs effizient kompiliert werden
Very nice. und elegant.
mMn einziges Manko: michl will beim overflow wieder auf den initial-wert zurücksetzen.
Würde vielleicht noch ein zweites Argument mitliefern, was den Initial-Wert übergibt

Aircode

Code: Alles auswählen

function increment(var arr: array of Integer, const Init:Integer): Boolean;
begin
  Inc(arr[high(arr)]);
  if arr[high(arr)]<2048 then
    Exit(False);
  { Overflow handling }
  arr[high(arr)]:=arr[high(arr)] mod 2048;  //Comment Zvoni: Bei Überlauf ergibt das hier 0
  If arr[high(arr)]=0 Then arr[high(arr)]:=Init;  //Erweiterung
  { wir sind beim letzten(ersten) digit, daher setzen wir result um einen overflow anzuzeigen }
  if high(arr)=low(arr) then
    Exit(True);
  { wenn wir nicht im letzten bit sind, dann schauen wir uns den array ohne das letzte feld an }
  Result:=increment(arr[low(arr)..high(arr)-1], arr[high(arr)-1]);  //Erweiterung
end;
.....
//Erster Aufruf
MyBool:=Increment(MyArray, MyArray[High(MyArray)]);
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1685
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Zahlen in array elegant hochzählen?

Beitrag von fliegermichl »

Vielen Dank für die Idee,

statt dem zusätzlichen Parameter mit dem Initialwert verwende ich succ(Length(arr)) als Initialisierung des jeweils letzten Eintrages.
Dann passt das.

Benutzeravatar
Zvoni
Beiträge: 450
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Zahlen in array elegant hochzählen?

Beitrag von Zvoni »

fliegermichl hat geschrieben: Mo 8. Sep 2025, 11:24 Vielen Dank für die Idee,

statt dem zusätzlichen Parameter mit dem Initialwert verwende ich succ(Length(arr)) als Initialisierung des jeweils letzten Eintrages.
Dann passt das.
Bist du dir da sicher?

Dein Ur-Array hat eine Länge von 12, succ(12) ist 13.....
Hätte ein arr[high(arr)]:=succ(arr[High(arr)-1]); erwartet wenn du es anstelle meines ... :=Init; setzen willst

EDIT: bzw. eher
arr[high(arr)]:=pred(length(arr));
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1685
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Zahlen in array elegant hochzählen?

Beitrag von fliegermichl »

Zvoni hat geschrieben: Mo 8. Sep 2025, 11:40 EDIT: bzw. eher
arr[high(arr)]:=pred(length(arr));
Meine ich ja. Danke für den Hinweis.

Antworten