Task: Juggler sequence




Go: package main

import (
    "fmt"
    "log"
    
    big "github.com/ncw/gmp"
    "rcu"
)

var zero = new(big.Int)
var one = big.NewInt(1)
var two = big.NewInt(2)

func juggler(n int64) (int, int, *big.Int, int) {
    if n < 1 {
        log.Fatal("Starting value must be a positive integer.")
    }
    count := 0
    maxCount := 0
    a := big.NewInt(n)
    max := big.NewInt(n)
    tmp := new(big.Int)
    for a.Cmp(one) != 0 {
        if tmp.Rem(a, two).Cmp(zero) == 0 {
            a.Sqrt(a)
        } else {
            tmp.Mul(a, a)
            tmp.Mul(tmp, a)
            a.Sqrt(tmp)
        }
        count++
        if a.Cmp(max) > 0 {
            max.Set(a)
            maxCount = count
        }
    }
    return count, maxCount, max, len(max.String())
}

func main() {
    fmt.Println("n    l[n]  i[n]  h[n]")
    fmt.Println("-----------------------------------")
    for n := int64(20); n < 40; n++ {
        count, maxCount, max, _ := juggler(n)
        cmax := rcu.Commatize(int(max.Int64()))
        fmt.Printf("%2d    %2d   %2d    %s\n", n, count, maxCount, cmax)
    }
    fmt.Println()
    nums := []int64{
        113, 173, 193, 2183, 11229, 15065, 15845, 30817, 48443, 275485, 1267909,
        2264915, 5812827, 7110201, 56261531, 92502777, 172376627, 604398963,
    }
    fmt.Println("       n      l[n]   i[n]   d[n]")
    fmt.Println("-------------------------------------")
    for _, n := range nums {
        count, maxCount, _, digits := juggler(n)
        cn := rcu.Commatize(int(n))
        fmt.Printf("%11s   %3d    %3d    %s\n", cn, count, maxCount, rcu.Commatize(digits))
    }
}








Ada: with Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;

procedure Juggler is

   subtype Number  is Long_Long_Integer;
   type Index_Type is new Natural;

   subtype Initial_Values is Number range 20 .. 39;

   generic
      Initial : Number;
   package Generic_Juggler is
      procedure Next (Value : out Number; Index : out Index_Type);
   end Generic_Juggler;

   package body Generic_Juggler is

      type Real is new Long_Long_Float;

      package Real_Math is
        new Ada.Numerics.Generic_Elementary_Functions (Real);

      K   : Index_Type := 0;
      A_K : Real       := Real (Initial);

      procedure Next (Value : out Number; Index : out Index_Type) is
         use Real_Math;
      begin
         Value := Number (A_K);
         Index := K;
         A_K := (if Number (A_K) mod 2 = 0
                 then Real'Floor (A_K ** 0.5)
                 else Real'Floor (A_K ** 1.5));
         K := K + 1;
      end Next;

   end Generic_Juggler;

   procedure Statistics (N   : Number;     L_N : out Index_Type;
                         H_N : out Number; I_N : out Index_Type)
   is
      package Juggler_Generator is new Generic_Juggler (Initial => N);
      use Juggler_Generator;
      Value : Number;
   begin
      H_N := 0;
      I_N := 0;
      loop
         Next (Value, L_N);
         if Value > H_N then
            H_N := Value;
            I_N := L_N;
         end if;
         exit when Value = 1;
      end loop;
   end Statistics;

   procedure Put_Table is
      package Number_IO is new Ada.Text_IO.Integer_IO (Number);
      package Index_IO  is new Ada.Text_IO.Integer_IO (Index_Type);
      use Ada.Text_IO, Number_IO, Index_IO;
      L_N : Index_Type;
      H_N : Number;
      I_N : Index_Type;
   begin
      Put_Line ("  N   L(N)            H(N)   I(N)");
      Put_Line ("
      for N in Initial_Values loop
         Statistics (N, L_N, H_N, I_N);
         Put (N, Width => 3);     Put (L_N, Width => 7);
         Put (H_N, Width => 16);  Put (I_N, Width => 7);  New_Line;
      end loop;
   end Put_Table;

begin
   Put_Table;
end Juggler;