diff options
Diffstat (limited to 'challenge-014')
| -rwxr-xr-x | challenge-014/joelle-maslak/perl5/ch-1.pl | 50 | ||||
| -rwxr-xr-x | challenge-014/joelle-maslak/perl6/ch-1.p6 | 44 |
2 files changed, 94 insertions, 0 deletions
diff --git a/challenge-014/joelle-maslak/perl5/ch-1.pl b/challenge-014/joelle-maslak/perl5/ch-1.pl new file mode 100755 index 0000000000..583a8d3956 --- /dev/null +++ b/challenge-014/joelle-maslak/perl5/ch-1.pl @@ -0,0 +1,50 @@ +#!/usr/bin/env perl +use v5.22; +use strict; +use warnings; + +# Turn on method signatures +use feature 'signatures'; +no warnings 'experimental::signatures'; + +use autodie; + +die("Usage: $0 <number of sequence elements>") unless @ARGV <= 1; +my $length = $ARGV[0] // 19; + +sub MAIN() { + say join ' ', map { van_eck($_) } 0..($length-1); +} + +my %cache_by_val = (0 => [0, 1]); +my @cache_by_pos = (0, 0); + +sub van_eck($pos) { + return 0 if $pos <= 1; + + return $cache_by_pos[$pos] if exists $cache_by_pos[$pos]; + + # Ensure cache is populated + for (my $p=0; $p<$pos; $p++) { van_eck($p) } + + my $n = $pos - 1; + + # We know that we must have been called in order. + my $prev = van_eck($n); + + my $current; + if (exists $cache_by_val{$prev} and scalar($cache_by_val{$prev}->@*) >= 2) { + my $m = $cache_by_val{$prev}->[-2]; + $current = $n - $m; + } else { + $current = 0; + } + $cache_by_pos[$pos] = $current; + $cache_by_val{$current} = [] unless exists $cache_by_val{$current}; + push $cache_by_val{$current}->@*, $pos; + + return $current; +} + +MAIN(); + diff --git a/challenge-014/joelle-maslak/perl6/ch-1.p6 b/challenge-014/joelle-maslak/perl6/ch-1.p6 new file mode 100755 index 0000000000..05f3653422 --- /dev/null +++ b/challenge-014/joelle-maslak/perl6/ch-1.p6 @@ -0,0 +1,44 @@ +#!/usr/bin/env perl6 +use v6; + +# +# Copyright © 2019 Joelle Maslak +# All Rights Reserved - See License +# + +sub MAIN(UInt:D $length = 19) { + my $seq = lazy gather { for 0..∞ -> $n { take van-eck($n) } } + + say $seq[^$length].join(" "); +} + +my %cache-by-val = 0 => [0, 1]; +my @cache-by-pos = 0, 0; + +multi sub van-eck(0 --> UInt:D) { 0 } +multi sub van-eck(1 --> UInt:D) { 0 } +multi sub van-eck(UInt:D $pos --> UInt:D) { + + return @cache-by-pos[$pos] if @cache-by-pos[$pos]:exists; + + # Ensure cache is populated. + for ^$pos -> $p { van-eck($p) } + + my $n = $pos - 1; + + # We know that we must have been called in order. + my $prev = van-eck($n); + + my $current; + if %cache-by-val{$prev} and %cache-by-val{$prev}.elems ≥ 2 { + my $m = %cache-by-val{$prev}[*-2]; + $current = $n - $m; + } else { + $current = 0; + } + @cache-by-pos[$pos] = $current; + ( %cache-by-val{$current} //= Array.new ).push: $pos; + + return $current; +} + |
