Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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.  
  14. MODULE hailst;
  15.  
  16. IMPORT In, Out, API, Console;
  17.  
  18.  
  19. CONST
  20.     maxCard = ROR(-2, 1) DIV 3;
  21.     List    = 1;
  22.     Count   = 2;
  23.     Max     = 3;
  24.  
  25.  
  26. VAR
  27.     a: INTEGER;
  28.  
  29.  
  30. PROCEDURE HALT(code: INTEGER);
  31. BEGIN
  32.     In.Ln; Console.exit(TRUE); API.exit(code)
  33. END HALT;
  34.  
  35.  
  36. PROCEDURE HailStone(start, _type: INTEGER): INTEGER;
  37. VAR
  38.     n, max, count, res: INTEGER;
  39.     exit: BOOLEAN;
  40.  
  41. BEGIN
  42.     count := 1;
  43.     n := start;
  44.     max := n;
  45.     exit := FALSE;
  46.     WHILE exit # TRUE DO
  47.         IF _type = List THEN
  48.             Out.Int (n, 12);
  49.             IF count MOD 6 = 0 THEN Out.Ln END
  50.         END;
  51.         IF n # 1 THEN
  52.             IF ODD(n) THEN
  53.                 IF n < maxCard THEN
  54.                     n := 3 * n + 1;
  55.                     IF n > max THEN max := n END
  56.                 ELSE
  57.                     Out.String("Exceeding max value for type INTEGER at:");
  58.                     Out.Ln;
  59.                     Out.String("n = ");       Out.Int(start, 1);
  60.                     Out.String(", count = "); Out.Int(count, 1);
  61.                     Out.String(", intermediate value ");
  62.                     Out.Int(n, 1);
  63.                     Out.String(". Aborting.");
  64.                     Out.Ln;
  65.                     HALT(2)
  66.                 END
  67.             ELSE
  68.                 n := n DIV 2
  69.             END;
  70.             INC(count)
  71.         ELSE
  72.             exit := TRUE
  73.         END
  74.     END;
  75.     IF _type = Max THEN res := max ELSE res := count END
  76.  
  77.     RETURN res
  78. END HailStone;
  79.  
  80.  
  81. PROCEDURE FindMax(num: INTEGER);
  82. VAR
  83.     val, maxCount, maxVal, cnt: INTEGER;
  84.  
  85. BEGIN
  86.     maxCount := 0;
  87.     maxVal := 0;
  88.     FOR val := 2 TO num DO
  89.         cnt := HailStone(val, Count);
  90.         IF cnt > maxCount THEN
  91.             maxVal := val;
  92.             maxCount := cnt
  93.         END
  94.     END;
  95.     Out.String("Longest sequence below "); Out.Int(num, 1);
  96.     Out.String(" is ");                    Out.Int(HailStone(maxVal, Count), 1);
  97.     Out.String(" for n = ");               Out.Int(maxVal, 1);
  98.     Out.String(" with an intermediate maximum of ");
  99.     Out.Int(HailStone(maxVal, Max), 1);
  100.     Out.Ln
  101. END FindMax;
  102.  
  103.  
  104. BEGIN
  105.     Console.open;
  106.  
  107.     a := HailStone(27, List);
  108.     Out.Ln;
  109.     Out.String("Iterations total = "); Out.Int(HailStone(27, Count), 1);
  110.     Out.String(" max value = ");       Out.Int(HailStone(27, Max), 1);
  111.     Out.Ln;
  112.     FindMax(100000);
  113.     Out.String("Done.");
  114.     Out.Ln; In.Ln;
  115.  
  116.     Console.exit(TRUE)
  117. END hailst.