Skip to content

Commit 3918d77

Browse files
authored
Add Zeckendorf in Pascal (#5532)
1 parent defd26f commit 3918d77

1 file changed

Lines changed: 90 additions & 0 deletions

File tree

archive/p/pascal/zeckendorf.pas

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
program Zeckendorf;
2+
3+
{$mode objfpc}{$H+}{$J-}{$modeswitch advancedrecords}
4+
5+
uses
6+
SysUtils;
7+
8+
const
9+
MAX_FIB_COUNT = {$IFDEF CPU64}92{$ELSE}46{$ENDIF};
10+
11+
type
12+
TNatural = {$IFDEF CPU64}UInt64{$ELSE}UInt32{$ENDIF};
13+
14+
TZeckendorf = record
15+
private
16+
FFibonacciTable: array[0..MAX_FIB_COUNT - 1] of TNatural;
17+
FActualCount: Integer;
18+
FInitialized: Boolean;
19+
procedure Initialize;
20+
public
21+
procedure DecomposeAndPrint(ANumber: TNatural);
22+
end;
23+
24+
procedure TZeckendorf.Initialize;
25+
var
26+
A, B, Next: TNatural;
27+
begin
28+
if FInitialized then Exit;
29+
30+
FFibonacciTable[0] := 1;
31+
FFibonacciTable[1] := 2;
32+
FActualCount := 2;
33+
A := 1;
34+
B := 2;
35+
36+
while (High(TNatural) - A >= B) and (FActualCount < MAX_FIB_COUNT) do
37+
begin
38+
Next := A + B;
39+
FFibonacciTable[FActualCount] := Next;
40+
Inc(FActualCount);
41+
A := B;
42+
B := Next;
43+
end;
44+
FInitialized := True;
45+
end;
46+
47+
procedure TZeckendorf.DecomposeAndPrint(ANumber: TNatural);
48+
var
49+
I: Integer;
50+
IsFirstTerm: Boolean;
51+
begin
52+
Initialize;
53+
54+
if ANumber = 0 then Exit;
55+
56+
IsFirstTerm := True;
57+
for I := FActualCount - 1 downto 0 do
58+
begin
59+
if FFibonacciTable[I] <= ANumber then
60+
begin
61+
if not IsFirstTerm then Write(', ') else IsFirstTerm := False;
62+
Write(FFibonacciTable[I]);
63+
Dec(ANumber, FFibonacciTable[I]);
64+
end;
65+
if ANumber = 0 then Break;
66+
end;
67+
WriteLn;
68+
end;
69+
70+
procedure ShowUsage;
71+
begin
72+
WriteLn('Usage: please input a non-negative integer');
73+
Halt(1);
74+
end;
75+
76+
var
77+
InputVal: TNatural;
78+
Code: Integer;
79+
Z: TZeckendorf;
80+
begin
81+
if (ParamCount <> 1) then ShowUsage;
82+
83+
Val(ParamStr(1), InputVal, Code);
84+
if (Code <> 0) or (Pos('-', ParamStr(1)) > 0) then ShowUsage;
85+
86+
if InputVal = 0 then
87+
WriteLn
88+
else
89+
Z.DecomposeAndPrint(InputVal);
90+
end.

0 commit comments

Comments
 (0)