--- collatz.orig 2024-07-27 23:53:49.665967800 +0100 +++ collatz 2024-07-28 03:21:55.085180253 +0100 @@ -119,11 +119,19 @@ return ( $number, $highest ); } +use Inline Pdlpp => 'DATA', clean_after_build => 0; +sub PDL::collatz_pdl { + PDL::_collatz_pdl_int(@_, my $n = PDL->null, my $h = PDL->null); + # Perl scalars because is across forked processes in MCE + map $_->sclr, $n, $h; +} + no warnings 'once'; #*collatz = \&collatz_longest; # choose collatz here #*collatz = \&collatz_longest_c1; # using T(x) notation - *collatz = \&collatz_longest_c2; # using compiler intrinsics +#*collatz = \&collatz_longest_c2; # using compiler intrinsics + *collatz = \&PDL::collatz_pdl; # using PDL my $m = shift || '1e7'; my ( @sizes, $chunk_size ); @@ -151,3 +159,27 @@ say "@$_" for ( sort { $a->[0] <=> $b->[0] } grep { $_->[1] == $highest } @sizes )[ 0..0 ]; + +__DATA__ +__Pdlpp__ +pp_def('collatz_pdl', + Pars => 'beg(); end(); [o]number(); [o]highest()', + GenericTypes => ['Q'], + PMCode => '', # trigger the _int but keep the Perl code in main body + Code => ' + PDL_Indx i, number = 0, highest = 0; + for ( i = $end(); i >= $beg(); i-- ) { + PDL_Indx n = i, steps = 0; + /* count using the T(x) notation */ + do { + n % 2 ? ( steps += 2, n = (3 * n + 1) >> 1 ) + : ( steps += 1, n = n >> 1 ); + } while ( n != 1 ); + if ( steps >= highest ) { + number = i, highest = steps; + } + } + $number() = number; + $highest() = highest; + ', +);