hailst.ob07 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. (*
  2. adapted to Oberon-07 by 0CodErr, KolibriOS team
  3. *)
  4. (*
  5. The Hailstone sequence of numbers can be generated
  6. from a starting positive integer, n by:
  7. IF n is 1 THEN the sequence ends.
  8. IF n is even THEN the next n of the sequence = n / 2
  9. IF n is odd THEN the next n of the sequence = (3 * n) + 1
  10. The (unproven) Collatz conjecture is that the hailstone sequence
  11. for any starting number always terminates.
  12. *)
  13. MODULE hailst;
  14. IMPORT In, Out, API, Console;
  15. CONST
  16. maxCard = ROR(-2, 1) DIV 3;
  17. List = 1;
  18. Count = 2;
  19. Max = 3;
  20. VAR
  21. a: INTEGER;
  22. PROCEDURE HALT(code: INTEGER);
  23. BEGIN
  24. In.Ln; Console.exit(TRUE); API.exit(code)
  25. END HALT;
  26. PROCEDURE HailStone(start, _type: INTEGER): INTEGER;
  27. VAR
  28. n, max, count, res: INTEGER;
  29. exit: BOOLEAN;
  30. BEGIN
  31. count := 1;
  32. n := start;
  33. max := n;
  34. exit := FALSE;
  35. WHILE exit # TRUE DO
  36. IF _type = List THEN
  37. Out.Int (n, 12);
  38. IF count MOD 6 = 0 THEN Out.Ln END
  39. END;
  40. IF n # 1 THEN
  41. IF ODD(n) THEN
  42. IF n < maxCard THEN
  43. n := 3 * n + 1;
  44. IF n > max THEN max := n END
  45. ELSE
  46. Out.String("Exceeding max value for type INTEGER at:");
  47. Out.Ln;
  48. Out.String("n = "); Out.Int(start, 1);
  49. Out.String(", count = "); Out.Int(count, 1);
  50. Out.String(", intermediate value ");
  51. Out.Int(n, 1);
  52. Out.String(". Aborting.");
  53. Out.Ln;
  54. HALT(2)
  55. END
  56. ELSE
  57. n := n DIV 2
  58. END;
  59. INC(count)
  60. ELSE
  61. exit := TRUE
  62. END
  63. END;
  64. IF _type = Max THEN res := max ELSE res := count END
  65. RETURN res
  66. END HailStone;
  67. PROCEDURE FindMax(num: INTEGER);
  68. VAR
  69. val, maxCount, maxVal, cnt: INTEGER;
  70. BEGIN
  71. maxCount := 0;
  72. maxVal := 0;
  73. FOR val := 2 TO num DO
  74. cnt := HailStone(val, Count);
  75. IF cnt > maxCount THEN
  76. maxVal := val;
  77. maxCount := cnt
  78. END
  79. END;
  80. Out.String("Longest sequence below "); Out.Int(num, 1);
  81. Out.String(" is "); Out.Int(HailStone(maxVal, Count), 1);
  82. Out.String(" for n = "); Out.Int(maxVal, 1);
  83. Out.String(" with an intermediate maximum of ");
  84. Out.Int(HailStone(maxVal, Max), 1);
  85. Out.Ln
  86. END FindMax;
  87. BEGIN
  88. Console.open;
  89. a := HailStone(27, List);
  90. Out.Ln;
  91. Out.String("Iterations total = "); Out.Int(HailStone(27, Count), 1);
  92. Out.String(" max value = "); Out.Int(HailStone(27, Max), 1);
  93. Out.Ln;
  94. FindMax(100000);
  95. Out.String("Done.");
  96. Out.Ln; In.Ln;
  97. Console.exit(TRUE)
  98. END hailst.