aboutsummaryrefslogtreecommitdiff
path: root/challenge-054/simon-proctor
diff options
context:
space:
mode:
authorSimon Proctor <simon.proctor@zoopla.co.uk>2020-04-03 13:27:43 +0100
committerSimon Proctor <simon.proctor@zoopla.co.uk>2020-04-03 13:27:43 +0100
commit1019d2a4b372017e55f59d3aca6850a80303764f (patch)
tree5228043ab218a5c8d0cd3ab5de92b9f12b2f1c26 /challenge-054/simon-proctor
parentedaeef5243a5ab571ce2d92da279c76f2cda8c24 (diff)
downloadperlweeklychallenge-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.p655
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;
+}