RosettaCodeData/Task/Hailstone-sequence/Pascal/hailstone-sequence.pascal

110 lines
2.3 KiB
Text
Raw Permalink Normal View History

2015-02-20 00:35:01 -05:00
program ShowHailstoneSequence;
{$IFDEF FPC}
{$MODE delphi} //or objfpc
{$Else}
{$Apptype Console} // for delphi
{$ENDIF}
uses
SysUtils;// format
2016-12-05 22:15:40 +01:00
const
maxN = 10*1000*1000;// for output 1000*1000*1000
2015-02-20 00:35:01 -05:00
type
2016-12-05 22:15:40 +01:00
tiaArr = array[0..1000] of Uint64;
2015-02-20 00:35:01 -05:00
tIntArr = record
iaMaxPos : integer;
2016-12-05 22:15:40 +01:00
iaArr : tiaArr
2015-02-20 00:35:01 -05:00
end;
2016-12-05 22:15:40 +01:00
tpiaArr = ^tiaArr;
function HailstoneSeqCnt(n: UInt64): NativeInt;
begin
result := 0;
//ensure n to be odd
while not(ODD(n)) do
Begin
inc(result);
n := n shr 1;
end;
IF n > 1 then
repeat
//now n == odd -> so two steps in one can be made
repeat
n := (3*n+1) SHR 1;inc(result,2);
until NOT(Odd(n));
//now n == even -> so only one step can be made
repeat
n := n shr 1; inc(result);
until odd(n);
until n = 1;
end;
2015-02-20 00:35:01 -05:00
2016-12-05 22:15:40 +01:00
procedure GetHailstoneSequence(aStartingNumber: NativeUint;var aHailstoneList: tIntArr);
2015-02-20 00:35:01 -05:00
var
2016-12-05 22:15:40 +01:00
maxPos: NativeInt;
2015-02-20 00:35:01 -05:00
n: UInt64;
2016-12-05 22:15:40 +01:00
pArr : tpiaArr;
2015-02-20 00:35:01 -05:00
begin
with aHailstoneList do
begin
2016-12-05 22:15:40 +01:00
maxPos := 0;
pArr := @iaArr;
2015-02-20 00:35:01 -05:00
end;
2016-12-05 22:15:40 +01:00
n := aStartingNumber;
pArr^[maxPos] := n;
while n <> 1 do
begin
if odd(n) then
n := (3*n+1)
else
n := n shr 1;
inc(maxPos);
pArr^[maxPos] := n;
end;
aHailstoneList.iaMaxPos := maxPos;
2015-02-20 00:35:01 -05:00
end;
var
2016-12-05 22:15:40 +01:00
i,Limit: NativeInt;
2015-02-20 00:35:01 -05:00
lList: tIntArr;
2016-12-05 22:15:40 +01:00
lAverageLength:Uint64;
lMaxSequence: NativeInt;
lMaxLength,lgth: NativeInt;
2015-02-20 00:35:01 -05:00
begin
2016-12-05 22:15:40 +01:00
lList.iaMaxPos := 0;
GetHailstoneSequence(27, lList);//319804831
with lList do
begin
Limit := iaMaxPos;
writeln(Format('sequence of %d has %d elements',[iaArr[0],Limit+1]));
write(iaArr[0],',',iaArr[1],',',iaArr[2],',',iaArr[3],'..');
For i := iaMaxPos-3 to iaMaxPos-1 do
write(iaArr[i],',');
writeln(iaArr[iaMaxPos]);
end;
Writeln;
2015-02-20 00:35:01 -05:00
2016-12-05 22:15:40 +01:00
lMaxSequence := 0;
lMaxLength := 0;
i := 1;
limit := 10*i;
writeln(' Limit : number with max length | average length');
repeat
lAverageLength:= 0;
repeat
lgth:= HailstoneSeqCnt(i);
inc(lAverageLength, lgth);
if lgth >= lMaxLength then
2015-02-20 00:35:01 -05:00
begin
2016-12-05 22:15:40 +01:00
lMaxSequence := i;
lMaxLength := lgth+1;
2015-02-20 00:35:01 -05:00
end;
2016-12-05 22:15:40 +01:00
inc(i);
until i = Limit;
Writeln(Format(' %10d : %9d | %4d | %7.3f',
[limit,lMaxSequence, lMaxLength,0.9*lAverageLength/Limit]));
limit := limit*10;
until Limit > maxN;
2015-02-20 00:35:01 -05:00
end.