AW: Das 3n+1 / 5n+1 Problem
Das Programm in FreeBasic würde etwa so aussehen:
Dim As UInt64 max64_3 = 18446744073709551615 / 3 - 1
Dim As UInt64 max64_5 = 18446744073709551615 / 5 - 1
Dim As UInt64 biggest_number
Dim As Integer runde
Function sequence(n As UInt64) As Integer
Dim As Integer count = 0
runde = 1
biggest_number = 0
Do
If n > max64_3 Then Return -1 ' Check auf Overflow (nach der Multiplikation)
n = 3 * n + 1
count += 1
If n > biggest_number Then biggest_number = n
While (n Mod 2) = 0
n /= 2
count += 1
Wend
If n < 8 Then Return count
If n > max64_5 Then Return -1 ' Check auf Overflow (nach der Multiplikation)
n = 5 * n + 1
count += 1
If n > biggest_number Then biggest_number = n
While (n Mod 2) = 0
n /= 2
count += 1
Wend
runde += 1
If n < 8 Then Return count
If count > 1000000 Then ' Infinite Loop
Return -2
End If
Loop
End Function
Sub Main()
Dim As UInt64 n
Dim As Integer count
For n = 5 To 372
count = sequence(n)
If count = -1 Then
Print n; " Overflow"
ElseIf count = -2 Then
Print n; " Infinite Loop"
Else
Print n; " "; runde; " "; count; " "; biggest_number
End If
Next
End Sub
Schaut für mich übersichtlicher aus als das C-Programm. Aber C war noch nie wirklich für übersichtlichen Quellcode bekannt, lach.
Für diejenigen, die sich in FreeBasic nicht so gut auskennen: count += 1 ist eine Kurzform für count = count + 1. Entsprechend bedeutet n /= 2 einfach n = n / 2
Ein entsprechendes Turbo-Pascal-Programm sieht ziemlich ähnlich aus, ich habe es aber nicht getestet.
program CollatzSequence;
uses
sysutils;
const
max64_3: UInt64 = 18446744073709551615 div 3 - 1;
max64_5: UInt64 = 18446744073709551615 div 5 - 1;
var
biggest_number: UInt64;
runde: Integer;
function Sequence(n: UInt64): Integer;
var
count: Integer;
begin
count := 0;
runde := 1;
biggest_number := 0;
repeat
if n > max64_3 then
Exit(-1); // Check auf Overflow (nach der Multiplikation)
n := 3 * n + 1;
Inc(count);
if n > biggest_number then
biggest_number := n;
while (n mod 2) = 0 do
begin
n := n div 2;
Inc(count);
end;
if n < 8 then
Exit(count);
if n > max64_5 then
Exit(-1); // Check auf Overflow (nach der Multiplikation)
n := 5 * n + 1;
Inc(count);
if n > biggest_number then
biggest_number := n;
while (n mod 2) = 0 do
begin
n := n div 2;
Inc(count);
end;
Inc(runde);
if n < 8 then
Exit(count);
if count > 1000000 then
Exit(-2); // Infinite Loop
until False;
end;
var
n: UInt64;
count: Integer;
begin
for n := 5 to 372 do
begin
count := Sequence(n);
if count = -1 then
WriteLn(n, ' Overflow')
else if count = -2 then
WriteLn(n, ' Infinite Loop')
else
WriteLn(n, ' ', runde, ' ', count, ' ', biggest_number);
end;
end.
Geändert von Hartmut (02.08.2023 um 19:16 Uhr)
|