-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathcollatz3t.pas
More file actions
210 lines (202 loc) · 5.31 KB
/
Copy pathcollatz3t.pas
File metadata and controls
210 lines (202 loc) · 5.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
program Collatz5n;
uses
FGL, webCRT;
type
TIntegerList = specialize TFPGList<int64>;
var
num : TIntegerList;
c,s,x : integer; // default to 0
nodiv3: boolean = false;
plus1 : boolean = false;
noalt : boolean = false;
use3n : boolean = false;
plus3 : boolean = false;
btn : boolean = false;
js : string = '';
function colorText(const s: string; const c: string = 'red'): string; inline;
begin
Result := '<font color="'+c+'">'+s+'</font>';
end;
procedure Summary;
var
g: boolean;
i,j,len,min,max,glide,delay: int64;
begin
webWriteln('<p><b>Summary:</b>');
// initialize variables
len := num.IndexOf(num.Last);
delay := num.IndexOf(1);
glide := num.First;
min := num.First;
max := num.First;
g := false;
// calculate summary
for i := 0 to len do
begin
j := num[i];
if ((c > 0) and (j < 0)) or // quit on out of range
((c < 0) and (j > 0)) then Break;
if j < min then min := j;
if j > max then max := j;
if (j < glide) and (not g) then
begin
glide := j;
g := true;
end;
end;
// print summary
webWriteln('• n: '+Int2Str(c));
webWriteln('• min: '+Int2Str(min)+' on step '+Int2Str(num.IndexOf(min)+1));
webWriteln('• max: '+Int2Str(max)+' on step '+Int2Str(num.IndexOf(max)+1));
if glide = num.First then
webWriteln('• glide: – (none)')
else
webWriteln('• glide: '+Int2Str(glide)+' on step '+Int2Str(num.IndexOf(glide)+1));
if delay > 0 then
webWriteln('• delay: '+Int2Str(delay+1)+' steps')
else
begin
webWrite('• delay: infinite steps ');
if ((c > 0) and (num.Last < 0)) or
((c < 0) and (num.Last > 0)) then
webWriteln('(divergent)')
else
webWriteln('(closed loop)');
end;
end;
procedure Collatz5(const n: int64);
var
i: integer;
d: boolean;
r: string;
begin
// sequence step
s := s+1;
r := Int2Str(s)+';';
// check for double
i := num.IndexOf(n);
d := (i <> -1);
if not d then num.Add(n);
// print current n
if n > 0 then r := r+'<code><big>'+(Int2Str(n))+'</big></code>;'
else r := r+'<code><big>'+colorText(Int2Str(n))+'</big></code>;';
(* compute next n *)
// quit on out of range
if ((c > 0) and (n < 0)) or ((c < 0) and (n > 0)) then
begin
webTableRow(r+colorText('out of range'));
webTableRow(';Note: Max <b>n</b> is 64-bit integer or 2<sup>63</sup>;;');
Exit;
end
// quit on loop (double n)
else if d then
begin
webTableRow(r+'back to step <b>'+colorText(Int2Str(i+1))+'</b>');
Exit;
end
// quit on finish (n=1)
else if (n = 1) or (n = -1) then
begin
webTableRow(r+'done');
Exit;
end
// check for even number
else if (n mod 2 = 0) then
begin
webTableRow(r+'n/2');
Collatz5(n div 2);
end
// check for division by 3
else if (not nodiv3) and (n mod 3 = 0) then
begin
webTableRow(r+colorText('n/3','limegreen'));
Collatz5(n div 3);
end
// check for odd number
else
begin
// flip to +3 or +1
if not noalt then plus3 := not plus3;
if n < 0 then
begin // check for negative
if plus3 then
begin
webTableRow(r+colorText(Int2Str(x)+'n-3','blue'));
Collatz5(x*n-3);
end
else
begin
webTableRow(r+colorText(Int2Str(x)+'n-1','fuchsia'));
Collatz5(x*n-1);
end;
end
else // compute on positive
begin
if plus3 then
begin
webTableRow(r+colorText(Int2Str(x)+'n+3','blue'));
Collatz5(x*n+3);
end
else
begin
webTableRow(r+colorText(Int2Str(x)+'n+1','fuchsia'));
Collatz5(x*n+1);
end;
end;
end;
end;
(* main program *)
begin
OpenHTML(true,true);
// app page title
webPageTitle('Another Collatz Conjecture: 5n+1 or 5n+3',
'Note: Number must <b>not</b> be zero.');
// input n
webWrite('<p>');
webWrite('Enter a number:',110); webRead(c);
// button position on mobile
if isMobile then
begin
webWriteln;
webWrite;
end;
webReadButton(btn,'GO','',true);
// computation options
webWrite('<p>');
webWrite('Options:',110);
webReadln(nodiv3,'no division by 3'); webWrite;
webReadln(plus1 ,'start with Xn+3'); webWrite;
webReadln(noalt ,'no switching'); webWrite;
webReadln(use3n ,'use 3n instead of 5n');
// compute sequence
if isWebInput then
begin
// apply options
num := TIntegerList.Create;
plus3 := not plus1;
if noalt then plus3 := not plus3;
if use3n then x := 3 else x := 5;
// table styling
writeln('<style>');
writeln('table { font-size: 11pt; }');
writeln('table td:nth-child(1) { text-align: right; }');
writeln('table td:nth-child(2) { text-align: right; min-width: 140px; }');
writeln('table td:nth-child(3) { text-align: center; font-size: smaller }');
writeln('</style>');
// print sequence
webWriteln('<b>Result:</b>');
webOpenTable('Step;N<small>step</small>;Operation','','t5n');
Collatz5(c);
webCloseTable;
// summary
Summary;
num.Free;
// js copy library
writeln('<script src="https://cdn.jsdelivr.net/clipboard.js/1.5.12/clipboard.min.js"></script>');
writeln('<script>new Clipboard(''.btn'');</script>');
end;
// copy button
if c <> 0 then
js := ' │ <button class="btn" data-clipboard-target="#t5n"> Copy Table to Clipboard </button>';
CloseHTML(true,js);
end.