diff options
| author | Simon Proctor <simon.proctor@zoopla.co.uk> | 2020-04-03 13:27:43 +0100 |
|---|---|---|
| committer | Simon Proctor <simon.proctor@zoopla.co.uk> | 2020-04-03 13:27:43 +0100 |
| commit | 1019d2a4b372017e55f59d3aca6850a80303764f (patch) | |
| tree | 5228043ab218a5c8d0cd3ab5de92b9f12b2f1c26 /challenge-054/simon-proctor | |
| parent | edaeef5243a5ab571ce2d92da279c76f2cda8c24 (diff) | |
| download | perlweeklychallenge-club-1019d2a4b372017e55f59d3aca6850a80303764f.tar.gz perlweeklychallenge-club-1019d2a4b372017e55f59d3aca6850a80303764f.tar.bz2 perlweeklychallenge-club-1019d2a4b372017e55f59d3aca6850a80303764f.zip | |
So here's a script for the extra credits. It's not quick
Diffstat (limited to 'challenge-054/simon-proctor')
| -rw-r--r-- | challenge-054/simon-proctor/raku/ch-2-extra.p6 | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/challenge-054/simon-proctor/raku/ch-2-extra.p6 b/challenge-054/simon-proctor/raku/ch-2-extra.p6 new file mode 100644 index 0000000000..6974180c5e --- /dev/null +++ b/challenge-054/simon-proctor/raku/ch-2-extra.p6 @@ -0,0 +1,55 @@ +#!/usr/bin/env raku + +use v6; + +#| Print the 20 longest Collatz chain for values up to 1000000 +multi sub MAIN( Bool :v(:$verbose)=False){ + constant MAX-VALUE = 1000000; + + my %collatz-chains; + + my \batch-size = MAX-VALUE div 10; + + my @promises; + my $start = 1; + + for (1..10) { + my $s = $start; + my $e = $start+batch-size-1; + @promises.push( start chain-batch($s,$e,$verbose) ); + $start+=batch-size; + } + + await @promises; + + my @largest = @promises.map( |*.result ).sort({$^b.elems <=> $^a.elems}).[^20]; + + .say for @largest.map( { "{$_.join("->")} : {$_.elems} steps" } ); +} + +multi sub chain( 1 ) { 1 } + +multi sub chain( UInt \n where { n %% 2 } ) is pure { ( n, |chain( n div 2 ) ); } + +multi sub chain( UInt \n where { n !%% 2 && n > 1 } ) is pure { ( n, |chain( (3 * n) + 1 ) ); } + + +sub chain-batch( UInt $start is copy, UInt $end is copy, Bool \verbose ) { + my @largest = []; + my $shortest = 0; + + say "got {$start} to {$end}" if verbose; + + for ($start..$end).reverse -> \val { + my $collatz = chain(val); + if $collatz.elems >= $shortest { + @largest = @largest.push($collatz).sort( { $^b.elems <=> $^a.elems} ).[^20].grep(*.defined); + if @largest.elems == 20 { + $shortest = @largest[*-1].elems; + } + } + say "{val} : {$collatz.elems} : $shortest" if verbose; + } + + return @largest; +} |
