Juggler sequence: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Raku}}: Add a Raku example)
m (→‎{{header|Raku}}: minor clean-up)
Line 161: Line 161:
my @j = .&juggler;
my @j = .&juggler;
my $max = @j.max;
my $max = @j.max;
printf "%2s %4d %4d %s\n", .&comma, +@j-1, @j.first( * == $max, :k), comma( $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]";
say "\n n l[n] i[n] d[n]";
(113, 173, 193, 2183, 11229, 15065, 15845, 30817
( 113, 173, 193, 2183, 11229, 15065, 15845, 30817 ).hyper(:1batch).map: {
#,48443, 275485, 1267909, 2264915, 5812827, 7110201
).hyper(:1batch).map: {
my $start = now;
my $start = now;
my @j = .&juggler;
my @j = .&juggler;
my $max = @j.max;
my $max = @j.max;
printf "%10s %4d %4d %10s %6.2f seconds\n", .&comma, +@j-1, @j.first( * == $max, :k),
printf "%10s %4d %4d %10s %6.2f seconds\n", .&comma, +@j-1, @j.first(* == $max, :k),
$max.chars.&comma, (now - $start);
$max.chars.&comma, (now - $start);
}</lang>
}</lang>
{{out}}
{{out}}
Line 205: Line 203:
15,065 66 25 11,723 2.05 seconds
15,065 66 25 11,723 2.05 seconds
15,845 139 43 23,889 10.75 seconds
15,845 139 43 23,889 10.75 seconds
30,817 93 39 45,391 19.60 seconds</pre>
30,817 93 39 45,391 19.60 seconds</pre>


=={{header|Wren}}==
=={{header|Wren}}==

Revision as of 15:09, 18 August 2021

Juggler sequence is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
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 k is even or a[k + 1] = floor(a[k] ^ 1.5) if 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 task


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



Go

Translation of: Wren
Library: Go-rcu

This took about 13.5 minutes to reach n = 5,812,827 on my machine (Intel core i7-8565U) though should be much quicker using a faster language with GMP. <lang go>package main

import (

   "fmt"
   "log"
   "math/big"
   "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,
   }
   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("%9s   %3d    %3d    %s\n", cn, count, maxCount, rcu.Commatize(digits))
   }

}</lang>

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

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.

<lang perl6>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 $t ≥ 0 { $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);

}</lang>

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

Wren

Library: Wren-fmt
Library: Wren-big

This took about 14.5 minutes to reach n = 15,845 on my machine and I gave up after that. <lang ecmascript>import "/fmt" for Fmt import "/big" for BigInt

var zero = BigInt.zero var one = BigInt.one var two = BigInt.two

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] 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])

}</lang>

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