RosettaCodeData/Task/Hailstone-sequence/Oberon/hailstone-sequence.oberon
2023-07-01 13:44:08 -04:00

80 lines
1.9 KiB
Text

MODULE hailst;
IMPORT Out;
CONST maxCard = MAX (INTEGER) DIV 3;
List = 1;
Count = 2;
Max = 3;
VAR a : INTEGER;
PROCEDURE HailStone (start, type : INTEGER) : INTEGER;
VAR n, max, count : INTEGER;
BEGIN
count := 1;
n := start;
max := n;
LOOP
IF type = List THEN
Out.Int (n, 12);
IF count MOD 6 = 0 THEN Out.Ln END
END;
IF n = 1 THEN EXIT END;
IF ODD (n) THEN
IF n < maxCard THEN
n := 3 * n + 1;
IF n > max THEN max := n END
ELSE
Out.String ("Exceeding max value for type INTEGER at: ");
Out.String (" n = "); Out.Int (start, 12);
Out.String (" , count = "); Out.Int (count, 12);
Out.String (" and intermediate value ");
Out.Int (n, 1);
Out.String (". Aborting.");
Out.Ln;
HALT (2)
END
ELSE
n := n DIV 2
END;
INC (count)
END;
IF type = Max THEN RETURN max ELSE RETURN count END
END HailStone;
PROCEDURE FindMax (num : INTEGER);
VAR val, maxCount, maxVal, cnt : INTEGER;
BEGIN
maxCount := 0;
maxVal := 0;
FOR val := 2 TO num DO
cnt := HailStone (val, Count);
IF cnt > maxCount THEN
maxVal := val;
maxCount := cnt
END
END;
Out.String ("Longest sequence below "); Out.Int (num, 1);
Out.String (" is "); Out.Int (HailStone (maxVal, Count), 1);
Out.String (" for n = "); Out.Int (maxVal, 1);
Out.String (" with an intermediate maximum of ");
Out.Int (HailStone (maxVal, Max), 1);
Out.Ln
END FindMax;
BEGIN
a := HailStone (27, List);
Out.Ln;
Out.String ("Iterations total = "); Out.Int (HailStone (27, Count), 12);
Out.String (" max value = "); Out.Int (HailStone (27, Max) , 12);
Out.Ln;
FindMax (1000000);
Out.String ("Done.");
Out.Ln
END hailst.