Juggler sequence

From Rosetta Code
Task
Juggler sequence
You are encouraged to solve this task according to the task description, using any language you may know.

Background of the   juggler sequence:

Juggler sequences were publicized by an American mathematician and author   Clifford A. Pickover.   The name of the sequence gets it's name from the similarity of the rising and falling nature of the numbers in the sequences,   much like balls in the hands of a juggler.


Description

A juggler sequence is an integer sequence that starts with a positive integer a[0], with each subsequent term in the sequence being defined by the recurrence relation:

            a[k + 1]  =  floor(a[k] ^ 0.5)    if a[k] is even    or       
            a[k + 1]  =  floor(a[k] ^ 1.5)    if a[k] is odd                                   

If a juggler sequence reaches 1, then all subsequent terms are equal to 1. This is known to be the case for initial terms up to 1,000,000 but it is not known whether all juggler sequences after that will eventually reach 1.


Task

Compute and show here the following statistics for juggler sequences with an initial term of a[n] where n is between 20 and 39 inclusive:

  • l[n] - the number of terms needed to reach 1.
  • h[n] - the maximum value reached in that sequence.
  • i[n] - the index of the term (starting from 0) at which the maximum is (first) reached.


If your language supports big integers with an integer square root function, also compute and show here the same statistics for as many as you reasonably can of the following values for n:

113, 173, 193, 2183, 11229, 15065, 15845, 30817, 48443, 275485, 1267909, 2264915, 5812827

Those with fast languages and fast machines may also like to try their luck at n = 7110201.

However, as h[n] for most of these numbers is thousands or millions of digits long, show instead of h[n]:

  • d[n] - the number of digits in h[n]


The results can be (partially) verified against the table here.


Related tasks


See also
  • oeis:A007320 Number of steps needed for Juggler sequence started at n to reach 1
  • oeis:A094716 Largest value in the Juggler sequence started at n



11l

Translation of: Nim
F juggler(n)
   V a = Int64(n)
   V r_count = 0
   V r_max = a
   V r_maxidx = 0
   L a != 1
      V f = Float(a)
      a = Int64(I a [&] 1 == 0 {sqrt(f)} E f * sqrt(f))
      r_count++
      I a > r_max
         r_max = a
         r_maxidx = r_count
   R (r_count, r_max, r_maxidx)

print(‘n   l[n]            h[n]  i[n]’)
print(‘------------------------------’)
L(n) 20..39
   V (l, h, i) = juggler(n)
   print(f:‘{n}   {l:2}  {h:14}     {i}’)
Output:
n   l[n]            h[n]  i[n]
------------------------------
20    3              20     0
21    9             140     4
22    3              22     0
23    9             110     1
24    3              24     0
25   11           52214     3
26    6              36     3
27    6             140     1
28    6              36     3
29    9             156     1
30    6              36     3
31    6             172     1
32    6              36     3
33    8            2598     2
34    6              36     3
35    8            2978     2
36    3              36     0
37   17  24906114455136     8
38    3              38     0
39   14          233046     3
Translation of: Python
F isqrt(BigInt x)
   assert(x >= 0)

   V q = BigInt(1)
   L q <= x
      q *= 4

   V z = x
   V r = BigInt(0)
   L q > 1
      q I/= 4
      V t = z - r - q
      r I/= 2
      I t >= 0
         z = t
         r += q

   R r

F juggler(k, countdig = 1B, maxiters = 1000)
   V (m, maxj, maxjpos) = (BigInt(k), BigInt(k), 0)
   L(i) 1 .< maxiters
      m = I m % 2 == 0 {isqrt(m)} E isqrt(m * m * m)
      I m >= maxj
         (maxj, maxjpos) = (m, i)
      I m == 1
         print(f:‘{k:9}{commatize(i):6}{maxjpos:6}{commatize(I countdig {String(maxj).len} E maxj):20}{I countdig {‘ digits’} E ‘’}’)
         R i

   print(‘ERROR: Juggler series starting with ’k‘ did not converge in ’maxiters‘ iterations’)

print("       n    l(n)  i(n)       h(n) or d(n)\n-------------------------------------------")
L(k) 20..39
   juggler(k, 0B)

L(k) [113, 173, 193, 2183, 11229, 15065]
   juggler(k)
Output:
       n    l(n)  i(n)       h(n) or d(n)
-------------------------------------------
       20     3     0                  20
       21     9     4                 140
       22     3     0                  22
       23     9     1                 110
       24     3     0                  24
       25    11     3              52,214
       26     6     3                  36
       27     6     1                 140
       28     6     3                  36
       29     9     1                 156
       30     6     3                  36
       31     6     1                 172
       32     6     3                  36
       33     8     2               2,598
       34     6     3                  36
       35     8     2               2,978
       36     3     0                  36
       37    17     8  24,906,114,455,136
       38     3     0                  38
       39    14     3             233,046
      113    16     9                  27 digits
      173    32    17                  82 digits
      193    73    47                 271 digits
     2183    72    32               5,929 digits
    11229   101    54               8,201 digits
    15065    66    25              11,723 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;
Output:
  N   L(N)            H(N)   I(N)
---------------------------------
 20      3              20      0
 21      9             140      4
 22      3              22      0
 23      9             110      1
 24      3              24      0
 25     11           52214      3
 26      6              36      3
 27      6             140      1
 28      6              36      3
 29      9             156      1
 30      6              36      3
 31      6             172      1
 32      6              36      3
 33      8            2598      2
 34      6              36      3
 35      8            2978      2
 36      3              36      0
 37     17  24906114455136      8
 38      3              38      0
 39     14          233046      3

AppleScript

Core language

Keeping within AppleScript's usable number range:

on juggler(n)
    script o
        property sequence : {n}
    end script
    
    set i to 1
    set {max, pos} to {n, i}
    repeat until (n = 1)
        set n to n ^ (n mod 2 + 0.5) div 1
        set end of o's sequence to n
        set i to i + 1
        if (n > max) then set {max, pos} to {n, i}
    end repeat
    
    return {n:n, sequence:o's sequence, |length|:i, max:max, maxPos:pos}
end juggler

on intToText(n)
    if (n < 2 ^ 29) then return n as integer as text
    set lst to {n mod 10 as integer}
    set n to n div 10
    repeat until (n = 0)
        set beginning of lst to n mod 10 as integer
        set n to n div 10
    end repeat
    
    return join(lst, "")
end intToText

on join(lst, delim)
    set astid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to delim
    set txt to lst as text
    set AppleScript's text item delimiters to astid
    return txt
end join

on task()
    set output to {}
    repeat with n from 20 to 39
        set {|length|:len, max:max, maxPos:pos} to juggler(n)
        set end of output to join({n, ": l[n] = ", len - 1, ", h[n] = ", intToText(max), ", i[n] = ", pos - 1}, "")
    end repeat
    
    return join(output, linefeed)
end task

task()
Output:
"20: l[n] = 3, h[n] = 20, i[n] = 0
21: l[n] = 9, h[n] = 140, i[n] = 4
22: l[n] = 3, h[n] = 22, i[n] = 0
23: l[n] = 9, h[n] = 110, i[n] = 1
24: l[n] = 3, h[n] = 24, i[n] = 0
25: l[n] = 11, h[n] = 52214, i[n] = 3
26: l[n] = 6, h[n] = 36, i[n] = 3
27: l[n] = 6, h[n] = 140, i[n] = 1
28: l[n] = 6, h[n] = 36, i[n] = 3
29: l[n] = 9, h[n] = 156, i[n] = 1
30: l[n] = 6, h[n] = 36, i[n] = 3
31: l[n] = 6, h[n] = 172, i[n] = 1
32: l[n] = 6, h[n] = 36, i[n] = 3
33: l[n] = 8, h[n] = 2598, i[n] = 2
34: l[n] = 6, h[n] = 36, i[n] = 3
35: l[n] = 8, h[n] = 2978, i[n] = 2
36: l[n] = 3, h[n] = 36, i[n] = 0
37: l[n] = 17, h[n] = 24906114455136, i[n] = 8
38: l[n] = 3, h[n] = 38, i[n] = 0
39: l[n] = 14, h[n] = 233046, i[n] = 3"

Shell script

One of AppleScript's main roles is telling other software to do things. This includes Unix executables, many of which come with the system. In the following, the 'do shell script' command feeds a script to the Bash shell, which script itself contains code to be passed to and executed by the "bc" executable. It's essentially a script within a script within a script. The text returned from "bc", which can handle larger numbers than core AppleScript, contains lines which are just the zeros returned by the 'juggler' function, so these are stripped out using "sed". The 'do shell script' command is supplied by the StandardAdditions OSAX which comes with the system as a standard AppleScript extension. So ironically, there's not a single command from the core language in the following code. But it's legitimate AppleScript and the input and output are both AppleScript text objects.

do shell script "echo '
define juggler(n) {
    #auto temp,i,max,pos
    #scale = 0;
    temp = n; i = 0; max = n; pos = i;
    while (temp > 1) {
        i = i + 1; temp = sqrt(temp ^ (1 + (temp % 2 * 2))); 
        if (temp > max) { max = temp; pos = i; }
    }
    if (n < 40) {
        print n,\": l[n] = \",i,\", h[n] = \",max, \", i[n] = \",pos,\"\\n\";
    } else {
        print n,\": l[n] = \",i,\", d[n] = \",length(max), \", i[n] = \",pos,\"\\n\";
    }
    return;
}

for (n = 20 ; n < 40 ; n++) { juggler(n); }
print \"\\n\";
juggler(113); juggler(173); juggler(193); juggler(2183); juggler(11229); juggler(15065);
juggler(15845); # 91 seconds so far.
juggler(30817); # Another 191 to here.
# juggler(48443) produced no result after running all night.
' | bc | sed -n '/^0$/ !p;'"
Output:
"20: l[n] = 3, h[n] = 20, i[n] = 0
21: l[n] = 9, h[n] = 140, i[n] = 4
22: l[n] = 3, h[n] = 22, i[n] = 0
23: l[n] = 9, h[n] = 110, i[n] = 1
24: l[n] = 3, h[n] = 24, i[n] = 0
25: l[n] = 11, h[n] = 52214, i[n] = 3
26: l[n] = 6, h[n] = 36, i[n] = 3
27: l[n] = 6, h[n] = 140, i[n] = 1
28: l[n] = 6, h[n] = 36, i[n] = 3
29: l[n] = 9, h[n] = 156, i[n] = 1
30: l[n] = 6, h[n] = 36, i[n] = 3
31: l[n] = 6, h[n] = 172, i[n] = 1
32: l[n] = 6, h[n] = 36, i[n] = 3
33: l[n] = 8, h[n] = 2598, i[n] = 2
34: l[n] = 6, h[n] = 36, i[n] = 3
35: l[n] = 8, h[n] = 2978, i[n] = 2
36: l[n] = 3, h[n] = 36, i[n] = 0
37: l[n] = 17, h[n] = 24906114455136, i[n] = 8
38: l[n] = 3, h[n] = 38, i[n] = 0
39: l[n] = 14, h[n] = 233046, i[n] = 3

113: l[n] = 16, d[n] = 27, i[n] = 9
173: l[n] = 32, d[n] = 82, i[n] = 17
193: l[n] = 73, d[n] = 271, i[n] = 47
2183: l[n] = 72, d[n] = 5929, i[n] = 32
11229: l[n] = 101, d[n] = 8201, i[n] = 54
15065: l[n] = 66, d[n] = 11723, i[n] = 25
15845: l[n] = 139, d[n] = 23889, i[n] = 43
30817: l[n] = 93, d[n] = 45391, i[n] = 39"

BQN

Juggle  {
    Step  ⌊⊢(0.5 + 2|⊢) 
    ¯100 + 3{   
        nimaxmaxterm  𝕩
        𝕊(term1) n+1, (max<term)imaxn, maxterm, Step term
    } 000𝕩
}

>"NLIH"  (⊢∾Juggle)¨ 20+↕20
Output:
┌─                            
╵ 'N' 'L' 'I' 'H'             
  20  3   0   20              
  21  9   4   140             
  22  3   0   22              
  23  9   1   110             
  24  3   0   24              
  25  11  3   52214           
  26  6   3   36              
  27  6   1   140             
  28  6   3   36              
  29  9   1   156             
  30  6   3   36              
  31  6   1   172             
  32  6   3   36              
  33  8   2   2598            
  34  6   3   36              
  35  8   2   2978            
  36  3   0   36              
  37  17  8   24906114455136  
  38  3   0   38              
  39  14  3   233046          
                             ┘


C#

Translation of: Java
using System;
using System.Collections.Generic;
using System.Numerics;

public class JugglerSequence
{
    public static void Main(string[] args)
    {
        Console.WriteLine(" n    l[n]  i[n]             h[n]");
        Console.WriteLine("---------------------------------");
        for (int number = 20; number <= 39; number++)
        {
            JugglerData result = Juggler(number);
            Console.WriteLine($"{number,2}{result.Count,7}{result.MaxCount,6}{result.MaxNumber,17}");
        }
        Console.WriteLine();

        List<int> values = new List<int> { 113, 173, 193, 2183, 11229, 15065, 15845, 30817 };
        Console.WriteLine("    n     l[n]   i[n]   d[n]");
        Console.WriteLine("----------------------------");
        foreach (int value in values)
        {
            JugglerData result = Juggler(value);
            Console.WriteLine($"{value,5}{result.Count,8}{result.MaxCount,7}{result.DigitCount,7}");
        }
    }

    private static JugglerData Juggler(int number)
    {
        if (number < 1)
        {
            throw new ArgumentException("Starting value must be >= 1: " + number);
        }
        BigInteger bigNumber = new BigInteger(number);
        int count = 0;
        int maxCount = 0;
        BigInteger maxNumber = bigNumber;
        while (!bigNumber.Equals(BigInteger.One))
{
    if (bigNumber.IsEven)
    {
        bigNumber = bigNumber.Sqrt();
    }
    else
    {
        BigInteger cubed = BigInteger.Pow(bigNumber, 3);
        bigNumber = cubed.Sqrt(); // Approximating the cube root by taking the square root of the cubed value.
    }
    count++;
    if (bigNumber.CompareTo(maxNumber) > 0)
    {
        maxNumber = bigNumber;
        maxCount = count;
    }
}

        return new JugglerData(count, maxCount, maxNumber, maxNumber.ToString().Length);
    }

    private class JugglerData
    {
        public int Count { get; }
        public int MaxCount { get; }
        public BigInteger MaxNumber { get; }
        public int DigitCount { get; }

        public JugglerData(int count, int maxCount, BigInteger maxNumber, int digitCount)
        {
            Count = count;
            MaxCount = maxCount;
            MaxNumber = maxNumber;
            DigitCount = digitCount;
        }
    }
}

public static class BigIntegerExtensions
{
    public static BigInteger Sqrt(this BigInteger n)
    {
        if (n == 0) return 0;
        if (n > 0)
        {
            int bitLength = Convert.ToInt32(Math.Ceiling(BigInteger.Log(n, 2)));
            BigInteger root = BigInteger.One << (bitLength / 2);

            while (!IsSqrt(n, root))
            {
                root += n / root;
                root /= 2;
            }

            return root;
        }
        throw new ArithmeticException("NaN");
    }

    private static bool IsSqrt(BigInteger n, BigInteger root)
    {
        BigInteger lowerBound = root * root;
        BigInteger upperBound = (root + 1) * (root + 1);
        return n >= lowerBound && n < upperBound;
    }
}
Output:
 n    l[n]  i[n]             h[n]
---------------------------------
20      3     0               20
21      9     4              140
22      3     0               22
23      9     1              110
24      3     0               24
25     11     3            52214
26      6     3               36
27      6     1              140
28      6     3               36
29      9     1              156
30      6     3               36
31      6     1              172
32      6     3               36
33      8     2             2598
34      6     3               36
35      8     2             2978
36      3     0               36
37     17     8   24906114455136
38      3     0               38
39     14     3           233046

    n     l[n]   i[n]   d[n]
----------------------------
  113      16      9     27
  173      32     17     82
  193      73     47    271
 2183      72     32   5929
11229     101     54   8201
15065      66     25  11723
15845     139     43  23889
30817      93     39  45391


C++

Translation of: Go
Library: GMP
#include <cassert>
#include <iomanip>
#include <iostream>
#include <string>

#include <gmpxx.h>

using big_int = mpz_class;

auto juggler(int n) {
    assert(n >= 1);
    int count = 0, max_count = 0;
    big_int a = n, max = n;
    while (a != 1) {
        if (a % 2 == 0)
            a = sqrt(a);
        else
            a = sqrt(big_int(a * a * a));
        ++count;
        if (a > max) {
            max = a;
            max_count = count;
        }
    }
    return std::make_tuple(count, max_count, max, max.get_str().size());
}

int main() {
    std::cout.imbue(std::locale(""));
    std::cout << "n    l[n]  i[n]   h[n]\n";
    std::cout << "--------------------------------\n";
    for (int n = 20; n < 40; ++n) {
        auto [count, max_count, max, digits] = juggler(n);
        std::cout << std::setw(2) << n << "    " << std::setw(2) << count
                  << "    " << std::setw(2) << max_count << "    " << max
                  << '\n';
    }
    std::cout << '\n';
    std::cout << "       n       l[n]   i[n]   d[n]\n";
    std::cout << "----------------------------------------\n";
    for (int n : {113, 173, 193, 2183, 11229, 15065, 15845, 30817, 48443,
                  275485, 1267909, 2264915, 5812827, 7110201, 56261531,
                  92502777, 172376627, 604398963}) {
        auto [count, max_count, max, digits] = juggler(n);
        std::cout << std::setw(11) << n << "    " << std::setw(3) << count
                  << "    " << std::setw(3) << max_count << "    " << digits
                  << '\n';
    }
}
Output:
n    l[n]  i[n]   h[n]
--------------------------------
20     3     0    20
21     9     4    140
22     3     0    22
23     9     1    110
24     3     0    24
25    11     3    52214
26     6     3    36
27     6     1    140
28     6     3    36
29     9     1    156
30     6     3    36
31     6     1    172
32     6     3    36
33     8     2    2598
34     6     3    36
35     8     2    2978
36     3     0    36
37    17     8    24906114455136
38     3     0    38
39    14     3    233046

       n       l[n]   i[n]   d[n]
----------------------------------------
        113     16      9    27
        173     32     17    82
        193     73     47    271
      2,183     72     32    5,929
     11,229    101     54    8,201
     15,065     66     25    11,723
     15,845    139     43    23,889
     30,817     93     39    45,391
     48,443    157     60    972,463
    275,485    225    148    1,909,410
  1,267,909    151     99    1,952,329
  2,264,915    149     89    2,855,584
  5,812,827    135     67    7,996,276
  7,110,201    205    119    89,981,517
 56,261,531    254     92    105,780,485
 92,502,777    191    117    139,486,096
172,376,627    262     90    449,669,621
604,398,963    327    172    640,556,693

F#

This task uses Isqrt_(integer_square_root)_of_X#F.23

// Juggler sequence. Nigel Galloway: August 19th., 2021
let J n=Seq.unfold(fun(n,i,g,l)->if n=1I then None else let e=match n.IsEven with true->Isqrt n |_->Isqrt(n**3) in Some((i,g,l),if e>i then (e,e,l+1,l+1) else (e,i,g,l+1)))(n,n,0,0)|>Seq.last
printfn " n  l[n] i[n]  h[n]\n___________________"; [20I..39I]|>Seq.iter(fun n->let i,g,l=J n in printfn $"%d{int n}%5d{l+1}%5d{g}   %A{i}")
printfn "      n  l[n] i[n]  d[n]\n________________________"; [113I;173I;193I;2183I;11229I;15065I;15845I;30817I]|>Seq.iter(fun n->let i,g,l=J n in printfn $"%8d{int n}%5d{l+1}%5d{g}   %d{(bigint.Log10>>int>>(+)1) i}")
Output:
 n  l[n] i[n]  h[n]
___________________
20    3    0   20
21    9    4   140
22    3    0   22
23    9    1   110
24    3    0   24
25   11    3   52214
26    6    3   36
27    6    1   140
28    6    3   36
29    9    1   156
30    6    3   36
31    6    1   172
32    6    3   36
33    8    2   2598
34    6    3   36
35    8    2   2978
36    3    0   36
37   17    8   24906114455136
38    3    0   38
39   14    3   233046

      n  l[n] i[n]  d[n]
________________________
     113   16    9   27
     173   32   17   82
     193   73   47   271
    2183   72   32   5929
   11229  101   54   8201
   15065   66   25   11723
   15845  139   43   23889
   30817   93   39   45391

Factor

Works with: Factor version 0.99 2021-06-02
USING: combinators formatting generalizations io kernel math
math.extras math.functions.integer-logs math.order math.ranges
sequences strings tools.memory.private ;

: next ( m -- n )
    dup odd? [ dup dup * * ] when integer-sqrt ;

: new-max ( l i h a -- l i h a )
    [ drop dup ] 2dip nip dup ;

: (step) ( l i h a -- l i h a )
    [ 1 + ] 3dip 2dup < [ new-max ] when next ;

: step ( l i h a -- l i h a )
    dup 1 = [ (step) ] unless ;

: juggler ( n quot: ( h -- obj ) -- l i h )
    [ 0 0 ] [ dup [ step ] to-fixed-point drop ] [ call ] tri*
    [ 1 [-] ] dip ; inline

CONSTANT: fmt "%-8s %-8s %-8s %s\n"

: row. ( n quot -- )
    dupd juggler [ commas ] 4 napply fmt printf ; inline

: dashes. ( n -- )
    CHAR: - <string> print ;

: header. ( str -- )
    [ "n" "l[n]" "i[n]" ] dip fmt printf 45 dashes. ;

: juggler. ( seq quot str -- )
    header. [ row. ] curry each ; inline

20 39 [a,b] [ ] "h[n]" juggler. nl

{ 113 173 193 2183 11229 15065 15845 30817 }
[ integer-log10 1 + ] "d[n]" juggler.
Output:
n        l[n]     i[n]     h[n]
---------------------------------------------
20       3        0        20
21       9        4        140
22       3        0        22
23       9        1        110
24       3        0        24
25       11       3        52,214
26       6        3        36
27       6        1        140
28       6        3        36
29       9        1        156
30       6        3        36
31       6        1        172
32       6        3        36
33       8        2        2,598
34       6        3        36
35       8        2        2,978
36       3        0        36
37       17       8        24,906,114,455,136
38       3        0        38
39       14       3        233,046

n        l[n]     i[n]     d[n]
---------------------------------------------
113      16       9        27
173      32       17       82
193      73       47       271
2,183    72       32       5,929
11,229   101      54       8,201
15,065   66       25       11,723
15,845   139      43       23,889
30,817   93       39       45,391

Go

Translation of: Wren
Library: Go-rcu

This originally took about 13.5 minutes to reach n = 5,812,827 on my machine (Intel core i7-8565U) using Go's native 'math/big' package.

However, when I exchanged that for Go's GMP wrapper there was a massive speed-up (now only 6.4 seconds to reach n = 5,812,827) and even 7,110,201 became viable with an overall time of 1 minute 40 seconds.

The next four record holders for the largest term (see talk page), are also doable but increased the overall time to nearly 24 minutes on my machine.

package main

import (
    "fmt"
    "log"
    //"math/big"
    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))
    }
}
Output:
n    l[n]  i[n]  h[n]
-----------------------------------
20     3    0    20
21     9    4    140
22     3    0    22
23     9    1    110
24     3    0    24
25    11    3    52,214
26     6    3    36
27     6    1    140
28     6    3    36
29     9    1    156
30     6    3    36
31     6    1    172
32     6    3    36
33     8    2    2,598
34     6    3    36
35     8    2    2,978
36     3    0    36
37    17    8    24,906,114,455,136
38     3    0    38
39    14    3    233,046

       n      l[n]   i[n]   d[n]
-------------------------------------
        113    16      9    27
        173    32     17    82
        193    73     47    271
      2,183    72     32    5,929
     11,229   101     54    8,201
     15,065    66     25    11,723
     15,845   139     43    23,889
     30,817    93     39    45,391
     48,443   157     60    972,463
    275,485   225    148    1,909,410
  1,267,909   151     99    1,952,329
  2,264,915   149     89    2,855,584
  5,812,827   135     67    7,996,276
  7,110,201   205    119    89,981,517
 56,261,531   254     92    105,780,485
 92,502,777   191    117    139,486,096
172,376,627   262     90    449,669,621
604,398,963   327    172    640,556,693

Haskell

Integer square root is computed as in Isqrt_(integer_square_root)_of_X#Haskell

import Text.Printf
import Data.List

juggler :: Integer -> [Integer]
juggler = takeWhile (> 1) . iterate (\x -> if odd x
                                           then isqrt (x*x*x)
                                           else isqrt x)

task :: Integer -> IO ()
task n = printf s n (length ns + 1) (i :: Int) (showMax m)
  where
    ns = juggler n
    (m, i) = maximum $ zip ns [0..]
    s = "n = %d length = %d maximal value at = %d (%s)\n"
    showMax n = let s = show n
                in if n > 10^100
                   then show (length s) ++ " digits" 
                   else show n 

main = do
  mapM_ task [20..39]
  putStrLn "\nTough guys\n"
  mapM_ task [ 113, 173, 193, 2183, 11229, 15065, 15845, 30817 ]
n = 20 length = 3 maximal value at = 0 (20)
n = 21 length = 10 maximal value at = 4 (140)
n = 22 length = 3 maximal value at = 0 (22)
n = 23 length = 10 maximal value at = 1 (110)
n = 24 length = 3 maximal value at = 0 (24)
n = 25 length = 11 maximal value at = 3 (52214)
n = 26 length = 7 maximal value at = 3 (36)
n = 27 length = 7 maximal value at = 1 (140)
n = 28 length = 7 maximal value at = 3 (36)
n = 29 length = 10 maximal value at = 1 (156)
n = 30 length = 7 maximal value at = 3 (36)
n = 31 length = 7 maximal value at = 1 (172)
n = 32 length = 7 maximal value at = 3 (36)
n = 33 length = 8 maximal value at = 2 (2598)
n = 34 length = 7 maximal value at = 3 (36)
n = 35 length = 8 maximal value at = 2 (2978)
n = 36 length = 4 maximal value at = 0 (36)
n = 37 length = 18 maximal value at = 8 (24906114455136)
n = 38 length = 4 maximal value at = 0 (38)
n = 39 length = 15 maximal value at = 3 (233046)

Tough guys

n = 113 length = 17 maximal value at = 9 (202924588924125339424550328)
n = 173 length = 33 maximal value at = 17 (4450608860210678234719664930918817118564659064289879586228390154864378511410864886)
n = 193 length = 74 maximal value at = 47 (271 digits)
n = 2183 length = 73 maximal value at = 32 (5929 digits)
n = 11229 length = 102 maximal value at = 54 (8201 digits)
n = 15065 length = 67 maximal value at = 25 (11723 digits)
n = 15845 length = 140 maximal value at = 43 (23889 digits)
n = 30817 length = 94 maximal value at = 39 (45391 digits)

J

jug=: <.@^ 0.5+2|]
would work if 64 bit floats were adequate for the task example, but they are not.

Instead, we take the square root of either the even number or the third power of the odd number:

jugx=: <.@%:@(^ 1x+2*2|])

Task examples:

require'format/printf'

task=: {{
  echo '%d: l: %d, h: %d, i:%d' sprintf y;(#;>./;]i.>./)jugx^:a: y
}}

   task"0(+i.)20
20: l: 4, h: 20, i:0
21: l: 10, h: 140, i:4
22: l: 4, h: 22, i:0
23: l: 10, h: 110, i:1
24: l: 4, h: 24, i:0
25: l: 12, h: 52214, i:3
26: l: 7, h: 36, i:3
27: l: 7, h: 140, i:1
28: l: 7, h: 36, i:3
29: l: 10, h: 156, i:1
30: l: 7, h: 36, i:3
31: l: 7, h: 172, i:1
32: l: 7, h: 36, i:3
33: l: 9, h: 2598, i:2
34: l: 7, h: 36, i:3
35: l: 9, h: 2978, i:2
36: l: 4, h: 36, i:0
37: l: 18, h: 24906114455136, i:8
38: l: 4, h: 38, i:0
39: l: 15, h: 233046, i:3

Sadly, J's extended precision implementation is antiquated (slow), hopefully that will be fixed before too long.

Still, some of the stretch exercises can be computed quickly:

taskx=: {{
  echo '%d: l: %d, d: %d, i:%d' sprintf y;(#;#@":@(>./);]i.>./)jugx^:a: y
}}

   taskx"0(113 173 193 2183 11229)
113: l: 17, d: 27, i:9
173: l: 33, d: 82, i:17
193: l: 74, d: 271, i:47
2183: l: 73, d: 5929, i:32
11229: l: 102, d: 8201, i:54

Java

import java.math.BigInteger;
import java.util.List;

public final class JugglerSequence {

	public static void main(String[] aArgs) {
		System.out.println(" n    l[n]  i[n]             h[n]");
		System.out.println("---------------------------------");
		for ( int number = 20; number <= 39; number++ ) {
		    JugglerData result = juggler(number);
		    System.out.println(String.format("%2d%7d%6d%17d",
		    	number, result.aCount, result.aMaxCount, result.aMaxNumber));
		}
		System.out.println();
		
		List<Integer> values = List.of( 113, 173, 193, 2183, 11229, 15065, 15845, 30817 );
		System.out.println("    n     l[n]   i[n]   d[n]");
		System.out.println("----------------------------");
		for ( int value : values ) {
		    JugglerData result = juggler(value);
		    System.out.println(String.format("%5d%8d%7d%7d",
		    	value, result.aCount, result.aMaxCount, result.aDigitCount));
		}
	}
	
	private static JugglerData juggler(int aNumber) {
		if ( aNumber < 1 ) {
			throw new IllegalArgumentException("Starting value must be >= 1: " + aNumber);
		}
	    BigInteger number = BigInteger.valueOf(aNumber);
	    int count = 0;
	    int maxCount = 0;
	    BigInteger maxNumber = number;
	    while ( ! number.equals(BigInteger.ONE) ) {
	    	number = number.testBit(0) ? number.pow(3).sqrt() : number.sqrt();
	        count = count + 1;
	        if ( number.compareTo(maxNumber) > 0 ) {
	            maxNumber = number;
	            maxCount = count;
	        }
	    }
	    return new JugglerData(count, maxCount, maxNumber, String.valueOf(maxNumber).length());
	}
	
	private static record JugglerData(int aCount, int aMaxCount, BigInteger aMaxNumber, int aDigitCount) {}

}
Output:
 n    l[n]  i[n]             h[n]
---------------------------------
20      3     0               20
21      9     4              140
22      3     0               22
23      9     1              110
24      3     0               24
25     11     3            52214
26      6     3               36
27      6     1              140
28      6     3               36
29      9     1              156
30      6     3               36
31      6     1              172
32      6     3               36
33      8     2             2598
34      6     3               36
35      8     2             2978
36      3     0               36
37     17     8   24906114455136
38      3     0               38
39     14     3           233046

    n     l[n]   i[n]   d[n]
----------------------------
  113      16      9     27
  173      32     17     82
  193      73     47    271
 2183      72     32   5929
11229     101     54   8201
15065      66     25  11723
15845     139     43  23889
30817      93     39  45391

jq

Translation of: Wren

Works with gojq, the Go implementation of jq

The following jq program uses `idivide/1`, `isqrt/0`, and `lpad/1` as defined at Isqrt_(integer_square_root)_of_X#jq.

def juggler:
  . as $n
  | if $n < 1 then "juggler starting value must be a positive integer." | error
    else { a: $n, count: 0, maxCount: 0, max: $n }
    | until (.a == 1;
        if .a % 2 == 0 then .a |= isqrt
        else .a = ((.a * .a * .a)|isqrt)
        end
        | .count += 1
        | if .a > .max
          then .max = .a
          | .maxCount = .count
	  else .
	  end)
    | [.count, .maxCount, .max, (.max|tostring|length)]
    end
;

def fmt(a;b;c;d):
  "\(.[0]|lpad(a)) \(.[1]|lpad(b)) \(.[2]|lpad(c)) \(.[3]|lpad(d))" ;
  
def task1:
  "n    l[n]  i[n]                h[n]",
  "-----------------------------------",
  (range(20; 40)
   | . as $n
   | juggler as $res
   | [$n, $res[0], $res[1], $res[2] ]
   | fmt(4;4;4;14) ) ;

def task2:
  def nums:[113, 173, 193, 2183, 11229, 15065, 15845, 30817];

 "   n     l[n]   i[n]     d[n]",
  "-----------------------------",
  (nums[]
   | . as $n
   | juggler as $res
   | [$n, $res[0], $res[1], $res[3] ]
   | fmt(6; 6; 6; 8) );

task1, "", task2
Output:
n    l[n]  i[n]                h[n]
-----------------------------------
  20    3    0             20
  21    9    4            140
  22    3    0             22
  23    9    1            110
  24    3    0             24
  25   11    3          52214
  26    6    3             36
  27    6    1            140
  28    6    3             36
  29    9    1            156
  30    6    3             36
  31    6    1            172
  32    6    3             36
  33    8    2           2598
  34    6    3             36
  35    8    2           2978
  36    3    0             36
  37   17    8 24906114455136
  38    3    0             38
  39   14    3         233046

   n     l[n]   i[n]     d[n]
-----------------------------
   113     16      9       27
   173     32     17       82
   193     73     47      271
  2183     72     32     5929
 11229    101     54     8201
 15065     66     25    11723
 15845    139     43    23889
 30817     93     39    45391

Julia

using Formatting

function juggler(k, countdig=true, maxiters=20000)
    m, maxj, maxjpos = BigInt(k), BigInt(k), BigInt(0)
    for i in 1:maxiters
        m = iseven(m) ? isqrt(m) : isqrt(m*m*m)
        if m >= maxj
            maxj, maxjpos  = m, i
        end
        if m == 1
            println(lpad(k, 9), lpad(i, 6), lpad(maxjpos, 6), lpad(format(countdig ?
                ndigits(maxj) : Int(maxj), commas=true), 20), countdig ? " digits" : "")
            return i
        end
    end
    error("Juggler series starting with $k did not converge in $maxiters iterations")
end

println("       n    l(n)  i(n)       h(n) or d(n)\n------------------------------------------")
foreach(k -> juggler(k, false), 20:39)
@time foreach(juggler,
    [113, 173, 193, 2183, 11229, 15065, 15845, 30817, 48443, 275485, 1267909,
     2264915, 5812827])
@time juggler(7110201)
Output:
       n    l(n)  i(n)       h(n) or d(n) 
------------------------------------------
       20     3     0                  20
       21     9     4                 140
       22     3     0                  22
       23     9     1                 110
       24     3     0                  24
       25    11     3              52,214
       26     6     3                  36
       27     6     1                 140
       28     6     3                  36
       29     9     1                 156
       30     6     3                  36
       31     6     1                 172
       32     6     3                  36
       33     8     2               2,598
       34     6     3                  36
       35     8     2               2,978
       36     3     0                  36
       37    17     8  24,906,114,455,136
       38     3     0                  38
       39    14     3             233,046
      113    16     9                  27 digits
      173    32    17                  82 digits
      193    73    47                 271 digits
     2183    72    32               5,929 digits
    11229   101    54               8,201 digits
    15065    66    25              11,723 digits
    15845   139    43              23,889 digits
    30817    93    39              45,391 digits
    48443   157    60             972,463 digits
   275485   225   148           1,909,410 digits
  1267909   151    99           1,952,329 digits
  2264915   149    89           2,855,584 digits
  5812827   135    67           7,996,276 digits
  4.969021 seconds (113.27 k allocations: 2.023 GiB, 0.29% gc time)
  7110201   205   119          89,981,517 digits
 89.493898 seconds (1.11 M allocations: 27.713 GiB, 1.19% gc time)

Mathematica / Wolfram Language

next[n_Integer] := If[EvenQ@n, Floor[Sqrt[n]], Floor[n^(3/2)]]

stats[n_Integer] :=
 
 Block[{data = Most@NestWhileList[next, n, # > 1 &], mx},
  mx = First@Ordering[data, -1];
  {n, Length[data], data[[mx]], mx - 1}]
  
{TableForm[Table[stats@n, {n, 20, 39}], 
 TableHeadings -> {None, {"n", "length", "max", "max pos"}}]
Output:

n length max max pos 20 3 20 0 21 9 140 4 22 3 22 0 23 9 110 1 24 3 24 0 25 11 52214 3 26 6 36 3 27 6 140 1 28 6 36 3 29 9 156 1 30 6 36 3 31 6 172 1 32 6 36 3 33 8 2598 2 34 6 36 3 35 8 2978 2 36 3 36 0 37 17 24906114455136 8 38 3 38 0 39 14 233046 3

Nim

Using only standard library, so limited to values of n less than 40.

import math, strformat

func juggler(n: Positive): tuple[count: int; max: uint64; maxIdx: int] =
  var a = n.uint64
  result = (0, a, 0)
  while a != 1:
    let f = float(a)
    a = if (a and 1) == 0: sqrt(f).uint64
        else: uint64(f * sqrt(f))
    inc result.count
    if a > result.max:
      result.max = a
      result.maxIdx = result.count

echo "n   l[n]            h[n]  i[n]"
echo "——————————————————————————————"
for n in 20..39:
  let (l, h, i) = juggler(n)
  echo &"{n}   {l:2}  {h:14}     {i}"
Output:
n   l[n]            h[n]  i[n]
——————————————————————————————
20    3              20     0
21    9             140     4
22    3              22     0
23    9             110     1
24    3              24     0
25   11           52214     3
26    6              36     3
27    6             140     1
28    6              36     3
29    9             156     1
30    6              36     3
31    6             172     1
32    6              36     3
33    8            2598     2
34    6              36     3
35    8            2978     2
36    3              36     0
37   17  24906114455136     8
38    3              38     0
39   14          233046     3

Perl

#!/usr/bin/perl

use strict; # https://rosettacode.org/wiki/Juggler_sequence
use warnings;
use Math::BigInt lib => 'GMP';

print "       n  l(n) i(n)  h(n) or d(n)\n";
print " -------  ---- ----  ------------\n";
for my $i ( 20 .. 39,
  113, 173, 193, 2183, 11229, 15065, 15845, 30817,
  48443, 275485, 1267909, 2264915, 5812827,
  7110201  # tried my luck, luck takes about 94 seconds
  )
  {
  my $max = my $n = Math::BigInt->new($i);
  my $at = my $count = 0;
  while( $n > 1 )
    {
    $n = sqrt( $n & 1 ? $n ** 3 : $n );
    $count++;
    $n > $max and ($max, $at) = ($n, $count);
    }

  if( length $max < 27 )
    {
    printf "%8d  %4d  %3d  %s\n", $i, $count, $at, $max;
    }
  else
    {
    printf "%8d  %4d  %3d  d(n) = %d digits\n", $i, $count, $at, length $max;
    }
  }
Output:
       n  l(n) i(n)  h(n) or d(n)
 -------  ---- ----  ------------
      20     3    0  20
      21     9    4  140
      22     3    0  22
      23     9    1  110
      24     3    0  24
      25    11    3  52214
      26     6    3  36
      27     6    1  140
      28     6    3  36
      29     9    1  156
      30     6    3  36
      31     6    1  172
      32     6    3  36
      33     8    2  2598
      34     6    3  36
      35     8    2  2978
      36     3    0  36
      37    17    8  24906114455136
      38     3    0  38
      39    14    3  233046
     113    16    9  d(n) = 27 digits
     173    32   17  d(n) = 82 digits
     193    73   47  d(n) = 271 digits
    2183    72   32  d(n) = 5929 digits
   11229   101   54  d(n) = 8201 digits
   15065    66   25  d(n) = 11723 digits
   15845   139   43  d(n) = 23889 digits
   30817    93   39  d(n) = 45391 digits
   48443   157   60  d(n) = 972463 digits
  275485   225  148  d(n) = 1909410 digits
 1267909   151   99  d(n) = 1952329 digits
 2264915   149   89  d(n) = 2855584 digits
 5812827   135   67  d(n) = 7996276 digits
 7110201   205  119  d(n) = 89981517 digits

Phix

Library: Phix/online

You can run this online here.

with javascript_semantics
include mpfr.e 

function juggler(integer n, bool bDigits=false)
    atom t0 = time(), t1 = time()+1
    assert(n>=1)
    mpz a = mpz_init(n),
        h = mpz_init(n)
    integer l = 0, 
            hi = 0
    while mpz_cmp_si(a,1)!=0 do
        if mpz_odd(a) then
            mpz_pow_ui(a,a,3)
        end if
        mpz_sqrt(a,a)
        l += 1
        if mpz_cmp(a,h)>0 then
            mpz_set(h,a)
            hi = l
        end if
        if platform()!=JS and time()>t1 then
            progress("working (l=%d)\r",{l})
            t1 = time()+1
        end if
    end while
    atom hd = iff(bDigits?mpz_sizeinbase(h,10):mpz_get_atom(h))
    t0 = time()-t0
    string t = iff(t0>=1?" ("&elapsed(t0)&")":"")
    return {n, l, hd, hi, t}
end function
 
procedure main()
    atom t0 = time()
    printf(1," n  l[n]                 h[n]  i[n]\n")
    printf(1,"-----------------------------------\n")
    for n=20 to 39 do
        printf(1,"%2d    %2d   %,18d    %2d %s\n", juggler(n))
    end for
    sequence nums = {113, 173, 193, 2183, 11229, 15065, 15845, 30817}
                    -- alas mpz_sqrt() throws a wobbly over the rest:
--                   48443, 275485, 1267909, 2264915, 5812827, 7110201}
    printf(1,"\n        n  l[n]    d[n]  i[n]\n")
    printf(1,"-----------------------------\n")
    --  ... and pwa/p2js(/mpfr.js) only copes with the first 3
    for i=1 to iff(platform()=JS?3:length(nums)) do
        printf(1,"%9d   %3d  %,6d    %2d %s\n", juggler(nums[i],true))
    end for
    ?elapsed(time()-t0)
end procedure
main()
Output:
 n  l[n]                 h[n]  i[n]
-----------------------------------
20     3                   20     0
21     9                  140     4
22     3                   22     0
23     9                  110     1
24     3                   24     0
25    11               52,214     3
26     6                   36     3
27     6                  140     1
28     6                   36     3
29     9                  156     1
30     6                   36     3
31     6                  172     1
32     6                   36     3
33     8                2,598     2
34     6                   36     3
35     8                2,978     2
36     3                   36     0
37    17   24,906,114,455,136     8
38     3                   38     0
39    14              233,046     3

        n  l[n]    d[n]  i[n]
-----------------------------
      113    16      27     9
      173    32      82    17
      193    73     271    47
     2183    72   5,929    32
    11229   101   8,201    54
    15065    66  11,723    25
    15845   139  23,889    43
    30817    93  45,391    39
"0.1s"

Actually pwa/p2js will cope a bit further than that 193, but at a pretty glacial rate (your browser's JavaScript BigInt implementation/performance might differ from mine):

     2183    72   5,929    32  (1 minute and 8s)
    11229   101   8,201    54  (2 minutes and 33s)
    15065    66  11,723    25  (7 minutes and 43s)
    15845   139  23,889    43  (1 hour, 10 minutes and 32s)
"1 hour, 21 minutes and 47s"

(Everything prior was over and done in 0.1s) I think I can fairly safely predict that 30817 would be over 4 hours. Should someone provide a better implementation of mpz_sqrt() for either or both of desktop/Phix and pwa/p2js's mpfr.js (the latter is currently a trivial 10 liner), things might improve...

Python

Slowed to a crawl at n of 1267909, so did not run for larger n.

from math import isqrt

def juggler(k, countdig=True, maxiters=1000):
    m, maxj, maxjpos = k, k, 0
    for i in range(1, maxiters):
        m = isqrt(m) if m % 2 == 0 else isqrt(m * m * m)
        if m >= maxj:
            maxj, maxjpos  = m, i
        if m == 1:
            print(f"{k: 9}{i: 6,}{maxjpos: 6}{len(str(maxj)) if countdig else maxj: 20,}{' digits' if countdig else ''}")
            return i

    print("ERROR: Juggler series starting with $k did not converge in $maxiters iterations")


print("       n    l(n)  i(n)       h(n) or d(n)\n-------------------------------------------")
for k in range(20, 40):
    juggler(k, False)

for k in [113, 173, 193, 2183, 11229, 15065, 15845, 30817, 48443, 275485, 1267909]:
    juggler(k)
Output:
       n    l(n)  i(n)         h(n) or d(n)
--------------------------------------------
       20     3     0                  20
       21     9     4                 140
       22     3     0                  22
       23     9     1                 110
       24     3     0                  24
       25    11     3              52,214
       26     6     3                  36
       27     6     1                 140
       28     6     3                  36
       29     9     1                 156
       30     6     3                  36
       31     6     1                 172
       32     6     3                  36
       33     8     2               2,598
       34     6     3                  36
       35     8     2               2,978
       36     3     0                  36
       37    17     8  24,906,114,455,136
       38     3     0                  38
       39    14     3             233,046
      113    16     9                  27 digits
      173    32    17                  82 digits
      193    73    47                 271 digits
     2183    72    32               5,929 digits
    11229   101    54               8,201 digits
    15065    66    25              11,723 digits
    15845   139    43              23,889 digits
    30817    93    39              45,391 digits
    48443   157    60             972,463 digits
   275485   225   148           1,909,410 digits
  1267909   151    99           1,952,329 digits

Quackery

  [ dip number$ 
    over size - 
    space swap of
    swap join echo$ ]          is recho   ( n n -->   )

  [ 1 & ]                      is odd     (   n --> b )

  [ dup dup * * ]              is cubed   (   n --> n )

  [ dup 1
    [ 2dup > while
      + 1 >>
      2dup / again ]
    drop nip ]                 is sqrt    (   n --> n )
 
  [ nested 
    [ dup -1 peek 1 != while
      dup -1 peek 
      dup odd if cubed
      sqrt join again ] ]      is juggler (   n --> [ ) 

  [ dup 4 recho
    juggler
    dup size 1 - 
    3 recho
    0 swap behead swap 
    witheach 
      [ 2dup < if
          [ rot drop 
            i^ 1+ unrot
            swap ]
        drop ]  
    15 recho 2 recho cr ]     is stats   (   n -->   )

  20 times [ i^ 20 + stats ]
Output:
  20  3             20 0
  21  9            140 4
  22  3             22 0
  23  9            110 1
  24  3             24 0
  25 11          52214 3
  26  6             36 3
  27  6            140 1
  28  6             36 3
  29  9            156 1
  30  6             36 3
  31  6            172 1
  32  6             36 3
  33  8           2598 2
  34  6             36 3
  35  8           2978 2
  36  3             36 0
  37 17 24906114455136 8
  38  3             38 0
  39 14         233046 3

Raku

Reaches 30817 fairly quickly but later values suck up enough memory that it starts thrashing the disk cache and performance drops off a cliff (on my system). Killed it after 10 minutes and capped list at 30817. Could rewrite to not try to hold entire sequence in memory at once, but probably not worth it. If you want sheer numeric calculation performance, Raku is probably not where it's at.

use Lingua::EN::Numbers;
sub juggler (Int $n where * > 0) { $n, { $_ +& 1 ?? .³.&isqrt !! .&isqrt } … 1 }

sub isqrt ( \x ) { my ( $X, $q, $r, $t ) =  x, 1, 0 ;
    $q +<= 2 while $q$X ;
    while $q > 1 {
        $q +>= 2; $t = $X - $r - $q; $r +>= 1;
        if $t0 { $X = $t; $r += $q }
    }
    $r
}

say " n  l[n]  i[n]   h[n]";
for 20..39 {
    my @j = .&juggler;
    my $max = @j.max;
    printf "%2s %4d  %4d    %s\n", .&comma, +@j-1, @j.first(* == $max, :k), comma $max;
}

say "\n      n     l[n]   i[n]    d[n]";
( 113, 173, 193, 2183, 11229, 15065, 15845, 30817 ).hyper(:1batch).map: {
    my $start = now;
    my @j = .&juggler;
    my $max = @j.max;
    printf "%10s %4d   %4d %10s   %6.2f seconds\n", .&comma, +@j-1, @j.first(* == $max, :k),
      $max.chars.&comma, (now - $start);
}
Output:
 n  l[n]  i[n]   h[n]
20    3     0    20
21    9     4    140
22    3     0    22
23    9     1    110
24    3     0    24
25   11     3    52,214
26    6     3    36
27    6     1    140
28    6     3    36
29    9     1    156
30    6     3    36
31    6     1    172
32    6     3    36
33    8     2    2,598
34    6     3    36
35    8     2    2,978
36    3     0    36
37   17     8    24,906,114,455,136
38    3     0    38
39   14     3    233,046

      n     l[n]   i[n]    d[n]
       113   16      9         27     0.01 seconds
       173   32     17         82     0.01 seconds
       193   73     47        271     0.09 seconds
     2,183   72     32      5,929     1.05 seconds
    11,229  101     54      8,201     1.98 seconds
    15,065   66     25     11,723     2.05 seconds
    15,845  139     43     23,889    10.75 seconds
    30,817   93     39     45,391    19.60 seconds

REXX

REXX doesn't have a native integer sqrt function, so one was utilized that was previously written.

Also, one optimization was to examine the last decimal digit for   oddness   (instead of getting the remainder when
dividing by two).

Another optimization was to reduce the number of digits after the   sqrt   was calculated.

/*REXX program  calculates and displays  the  juggler sequence  for any positive integer*/
numeric digits 20                                /*define the number of decimal digits. */
parse arg LO HI list                             /*obtain optional arguments from the CL*/
if LO='' | LO=","  then do; LO= 20; HI= 39; end  /*Not specified?  Then use the default.*/
if HI='' | HI=","  then HI= LO                   /* "      "         "   "   "     "    */
w= length( commas(HI) )                          /*find the max width of any number  N. */
d= digits();     dd= d + d%3 + 1                 /*get # numeric digits; another version*/
if LO>0  then say c('n',w)    c("steps",7)    c('maxIndex',8)   c("biggest term"    ,dd)
if LO>0  then say c('' ,w,.)  c(""     ,7,.)  c(''        ,8,.) c(""                ,dd,.)

    do n=LO  to HI while n>0; steps= juggler(n)  /*invoke JUGGLER: find the juggler num.*/
    nc= commas(n)                                /*maybe add commas to  N.              */
    say right(nc, w)      c(steps, 8)     c(imx, 8)      right( commas(mx), dd-1)
    end   /*n*/
                                                 /*biggest term isn't shown for list #s.*/
xtra= words(list)                                /*determine how many numbers in list.  */
if xtra==0  then exit 0                          /*no special ginormous juggler numbers?*/
w= max(9, length( commas( word(list, xtra) ) ) ) /*find the max width of any list number*/
say;             say;             say
say c('n',w)     c("steps",7)     c('maxIndex',8)     c("max number of digits",dd)
say c('' ,w,.)   c(""     ,7,.)   c(''        ,8,.)   c(""                    ,dd,.)

         do p=1  for xtra;     n= word(list, p)  /*process each of the numbers in list. */
         steps= juggler(n);    nc= commas(n)     /*get a number & pass it on to JUGGLER.*/
         say right(nc, w)   c(steps, 8)   c(imx, 8)      right( commas(length(mx)), dd-1)
         end   /*p*/
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
c:      parse arg c1,c2,c3; if c3==''  then c3= ' '; else c3= '─'; return center(c1,c2,c3)
commas: parse arg ?;  do jc=length(?)-3  to 1  by -3; ?=insert(',', ?, jc); end;  return ?
/*──────────────────────────────────────────────────────────────────────────────────────*/
Isqrt:  procedure; parse arg x;  q= 1;  r= 0     /*obtain X;  R  will be the Isqrt(X).  */
           do until q>x;  q= q * 4               /*multiply   Q   by four until > X.    */
           end   /*until*/
               do while q>1;  q= q % 4           /*processing while Q>1;  quarter Q.    */
               t= x - r - q;  r= r % 2           /*set T ──► X-R-Q;       halve R.      */
               if t>=0  then do; x= t; r= r + q  /*T≥0?  Then set X ──► T;  add Q ──► R.*/
                             end
               end   /*while*/;    return r      /*return the integer square root of  X.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
juggler: parse arg #;  imx= 0;  mx= #            /*get N;  set index of MX and MX ──► 0.*/
         @.=0; @.1=1; @.3=1; @.5=1; @.7=1; @.9=1 /*set semaphores (≡1) for odd dec. digs*/
           do j=1  until z==1                    /*here is where we begin to juggle.    */
           parse var  #  ''  -1  _               /*obtain the last decimal digit of  #. */
           if @._  then do;       cube= #*#*#    /*Odd? Then compute integer sqrt(#**3).*/
                        if pos(., cube)>0  then do    /*need to increase decimal digits.*/
                                                parse var  cube    with    'E'  x
                                                if x>=digits()  then numeric digits x+2
                                                end
                        z= Isqrt(#*#*#)          /*compute the integer sqrt(#**3)       */
                        end
                   else z= Isqrt(#)              /*Even? Then compute integer sqrt(#).  */
           L= length(z)
           if L>=d  then numeric digits L+1      /*reduce the number of numeric digits. */
           if z>mx  then do;  mx= z; imx= j; end /*found a new max;  set MX;  set IMX.  */
           #= z
           end   /*j*/;                 return j
output   when using the inputs:     ,   ,   113   173   193   2183   11229   15065   30817   48443
n   steps  maxIndex        biggest term
── ─────── ──────── ───────────────────────────
20    3        0                             20
21    9        4                            140
22    3        0                             22
23    9        1                            110
24    3        0                             24
25    11       3                         52,214
26    6        3                             36
27    6        1                            140
28    6        3                             36
29    9        1                            156
30    6        3                             36
31    6        1                            172
32    6        3                             36
33    8        2                          2,598
34    6        3                             36
35    8        2                          2,978
36    3        0                             36
37    17       8             24,906,114,455,136
38    3        0                             38
39    14       3                        233,046


    n      steps  maxIndex    max number of digits
───────── ─────── ──────── ───────────────────────────
      113    16       9                             27
      173    32       17                            82
      193    73       47                           271
    2,183    72       32                         5,929
   11,229   101       54                         8,201
   15,065    66       25                        11,723
   15,845   139       43                        23,889
   30,817    93       39                        45,391
   48,443   157       60                       972,463

RPL

≪ 0 SWAP DUP2 
   DO 
     DUP 2 MOD 1.5 0.5 IFTE ^ FLOOR 
     SWAP 1 + SWAP 
     IF 3 PICK OVER < THEN ROT DROP DUP ROT ROT 4 ROLL DROP OVER 4 ROLLD END 
  UNTIL DUP 1 == END 
  DROP SWAP R→B ROT 3 →LIST 
≫ 'JUGLR' STO

≪ { "n" "l[n}" "h[n}" "i[n}" }
   20 39 FOR n { } n + n JUGLR + NEXT
≫ 'TASK' STO
Output:
21: { "n" "l[n}" "h[n}" "i[n}" }
20: { 20 3 #20 0 }
19: { 21 9 # 140d 4 }
18: { 22 3 # 22d 0 }
17: { 23 9 # 110d 1 }
16: { 24 3 # 24d 0 }
15: { 25 11 # 52214d 3 }
14: { 26 6 # 36d 3 }
13: { 27 6 # 140d 1 }
12: { 28 6 # 36d 3 }
11: { 29 9 # 156d 1 }
10: { 30 6 # 36d 3 }
9: { 31 6 # 172d 1 }
8: { 32 6  # 36d 3 }
7: { 33 8 # 2598d 2 }
6: { 34 6 # 36d 3 }
5: { 35 8 # 2978d 2 }
4: { 36 3 # 36d 0 }
3: { 37 17 # 24906114455136d 8 }
2: { 38 3 # 38d 0 }
1: { 39 14 # 233046d 3 }

Ruby

def juggler(k) = k.even? ? Integer.sqrt(k) : Integer.sqrt(k*k*k)

(20..39).chain([113, 173, 193, 2183, 11229, 15065, 15845, 30817, 48443, 275485, 1267909, 2264915]).each do |k|
  k1 = k
  l = h = i = 0
  until k == 1 do
    h, i = k, l if k > h
    l += 1
    k =  juggler(k)
  end
  if k1 < 40 then
    puts "#{k1}: l[n] = #{l}, h[n] = #{h}, i[n] = #{i}"
  else
    puts "#{k1}: l[n] = #{l}, d[n] = #{h.to_s.size}, i[n] = #{i}"
  end
end
Output:
20: l[n] = 3, h[n] = 20, i[n] = 0
21: l[n] = 9, h[n] = 140, i[n] = 4
22: l[n] = 3, h[n] = 22, i[n] = 0
23: l[n] = 9, h[n] = 110, i[n] = 1
24: l[n] = 3, h[n] = 24, i[n] = 0
25: l[n] = 11, h[n] = 52214, i[n] = 3
26: l[n] = 6, h[n] = 36, i[n] = 3
27: l[n] = 6, h[n] = 140, i[n] = 1
28: l[n] = 6, h[n] = 36, i[n] = 3
29: l[n] = 9, h[n] = 156, i[n] = 1
30: l[n] = 6, h[n] = 36, i[n] = 3
31: l[n] = 6, h[n] = 172, i[n] = 1
32: l[n] = 6, h[n] = 36, i[n] = 3
33: l[n] = 8, h[n] = 2598, i[n] = 2
34: l[n] = 6, h[n] = 36, i[n] = 3
35: l[n] = 8, h[n] = 2978, i[n] = 2
36: l[n] = 3, h[n] = 36, i[n] = 0
37: l[n] = 17, h[n] = 24906114455136, i[n] = 8
38: l[n] = 3, h[n] = 38, i[n] = 0
39: l[n] = 14, h[n] = 233046, i[n] = 3
113: l[n] = 16, d[n] = 27, i[n] = 9
173: l[n] = 32, d[n] = 82, i[n] = 17
193: l[n] = 73, d[n] = 271, i[n] = 47
2183: l[n] = 72, d[n] = 5929, i[n] = 32
11229: l[n] = 101, d[n] = 8201, i[n] = 54
15065: l[n] = 66, d[n] = 11723, i[n] = 25
15845: l[n] = 139, d[n] = 23889, i[n] = 43
30817: l[n] = 93, d[n] = 45391, i[n] = 39
48443: l[n] = 157, d[n] = 972463, i[n] = 60
275485: l[n] = 225, d[n] = 1909410, i[n] = 148
1267909: l[n] = 151, d[n] = 1952329, i[n] = 99
2264915: l[n] = 149, d[n] = 2855584, i[n] = 89

Wren

Wren CLI

Library: Wren-fmt
Library: Wren-big

This took just over 17 minutes to reach n = 30,817 on my machine and I gave up after that.

import "./fmt" for Fmt
import "./big" for BigInt

var one  = BigInt.one

var juggler = Fn.new { |n|
    if (n < 1) Fiber.abort("Starting value must be a positive integer.")
    var a = BigInt.new(n)
    var count = 0
    var maxCount = 0
    var max = a.copy()
    while (a != one) {
        if (a.isEven) {
            a = a.isqrt
        } else {
            a = (a.square * a).isqrt
        }
        count = count + 1
        if (a > max) {
            max = a
            maxCount = count
        }
    }
    return [count, maxCount, max, max.toString.count]
}

System.print("n    l[n]  i[n]  h[n]")
System.print("-----------------------------------") 
for (n in 20..39) {
    var res = juggler.call(n)
    Fmt.print("$2d    $2d   $2d    $,i", n, res[0], res[1], res[2])
}
System.print()
var nums = [113, 173, 193, 2183, 11229, 15065, 15845, 30817]
System.print("   n     l[n]   i[n]   d[n]")
System.print("----------------------------")
for (n in nums) {
    var res = juggler.call(n)
    Fmt.print("$,6d   $3d    $3d   $,6i", n, res[0], res[1], res[3])
}
Output:
n    l[n]  i[n]  h[n]
-----------------------------------
20     3    0    20
21     9    4    140
22     3    0    22
23     9    1    110
24     3    0    24
25    11    3    52,214
26     6    3    36
27     6    1    140
28     6    3    36
29     9    1    156
30     6    3    36
31     6    1    172
32     6    3    36
33     8    2    2,598
34     6    3    36
35     8    2    2,978
36     3    0    36
37    17    8    24,906,114,455,136
38     3    0    38
39    14    3    233,046

n        l[n]   i[n]   d[n]
----------------------------
   113    16      9       27
   173    32     17       82
   193    73     47      271
 2,183    72     32    5,929
11,229   101     54    8,201
15,065    66     25   11,723
15,845   139     43   23,889
30,817    93     39   45,391


Embedded

Library: Wren-gmp

Massive speed-up, of course, when one brings in GMP. Now takes about 1 minute 48 seconds to reach 7,110,201 which is not much slower than Go on the same machine!

/* Juggler_sequence_2.wren */

import "./gmp" for Mpz
import "./fmt" for Fmt

var one  = Mpz.one

var juggler = Fn.new { |n|
    if (n < 1) Fiber.abort("Starting value must be a positive integer.")
    var a = Mpz.from(n)
    var count = 0
    var maxCount = 0
    var max = a.copy()
    while (a != one) {
        if (a.isEven) {
            a.sqrt
        } else {
            a.cube.sqrt
        }
        count = count + 1
        if (a > max) {
            max.set(a)
            maxCount = count
        }
    }
    return [count, maxCount, max, max.toString.count]
}

System.print("n    l[n]  i[n]  h[n]")
System.print("-----------------------------------")
for (n in 20..39) {
    var res = juggler.call(n)
    Fmt.print("$2d    $2d   $2d    $,i", n, res[0], res[1], res[2])
}
System.print()
var nums = [
    113, 173, 193, 2183, 11229, 15065, 15845, 30817, 48443,
    275485, 1267909, 2264915, 5812827, 7110201
]

System.print("     n      l[n]   i[n]   d[n]")
System.print("-----------------------------------")
for (n in nums) {
    var res = juggler.call(n)
    Fmt.print("$,9d   $3d    $3d    $,i", n, res[0], res[1], res[3])
}
Output:
n    l[n]  i[n]  h[n]
-----------------------------------
20     3    0    20
21     9    4    140
22     3    0    22
23     9    1    110
24     3    0    24
25    11    3    52,214
26     6    3    36
27     6    1    140
28     6    3    36
29     9    1    156
30     6    3    36
31     6    1    172
32     6    3    36
33     8    2    2,598
34     6    3    36
35     8    2    2,978
36     3    0    36
37    17    8    24,906,114,455,136
38     3    0    38
39    14    3    233,046

     n      l[n]   i[n]   d[n]
-----------------------------------
      113    16      9    27
      173    32     17    82
      193    73     47    271
    2,183    72     32    5,929
   11,229   101     54    8,201
   15,065    66     25    11,723
   15,845   139     43    23,889
   30,817    93     39    45,391
   48,443   157     60    972,463
  275,485   225    148    1,909,410
1,267,909   151     99    1,952,329
2,264,915   149     89    2,855,584
5,812,827   135     67    7,996,276
7,110,201   205    119    89,981,517