(* adapted to Oberon-07 by 0CodErr, KolibriOS team *) (* The Hailstone sequence of numbers can be generated from a starting positive integer, n by: IF n is 1 THEN the sequence ends. IF n is even THEN the next n of the sequence = n / 2 IF n is odd THEN the next n of the sequence = (3 * n) + 1 The (unproven) Collatz conjecture is that the hailstone sequence for any starting number always terminates. *) MODULE hailst; IMPORT In, Out, API, Console; CONST maxCard = ROR(-2, 1) DIV 3; List = 1; Count = 2; Max = 3; VAR a: INTEGER; PROCEDURE HALT(code: INTEGER); BEGIN In.Ln; Console.exit(TRUE); API.exit(code) END HALT; PROCEDURE HailStone(start, _type: INTEGER): INTEGER; VAR n, max, count, res: INTEGER; exit: BOOLEAN; BEGIN count := 1; n := start; max := n; exit := FALSE; WHILE exit # TRUE DO IF _type = List THEN Out.Int (n, 12); IF count MOD 6 = 0 THEN Out.Ln END END; IF n # 1 THEN 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.Ln; Out.String("n = "); Out.Int(start, 1); Out.String(", count = "); Out.Int(count, 1); Out.String(", intermediate value "); Out.Int(n, 1); Out.String(". Aborting."); Out.Ln; HALT(2) END ELSE n := n DIV 2 END; INC(count) ELSE exit := TRUE END END; IF _type = Max THEN res := max ELSE res := count END RETURN res 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 Console.open; a := HailStone(27, List); Out.Ln; Out.String("Iterations total = "); Out.Int(HailStone(27, Count), 1); Out.String(" max value = "); Out.Int(HailStone(27, Max), 1); Out.Ln; FindMax(100000); Out.String("Done."); Out.Ln; In.Ln; Console.exit(TRUE) END hailst.