diff options
| -rw-r--r-- | challenge-122/polettix/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-122/polettix/blog1.txt | 1 | ||||
| -rw-r--r-- | challenge-122/polettix/perl/ch-1.pl | 25 | ||||
| -rw-r--r-- | challenge-122/polettix/perl/ch-2.pl | 102 | ||||
| -rw-r--r-- | challenge-122/polettix/raku/ch-1.raku | 21 | ||||
| -rw-r--r-- | challenge-122/polettix/raku/ch-2.raku | 48 |
6 files changed, 198 insertions, 0 deletions
diff --git a/challenge-122/polettix/blog.txt b/challenge-122/polettix/blog.txt new file mode 100644 index 0000000000..d966e0255b --- /dev/null +++ b/challenge-122/polettix/blog.txt @@ -0,0 +1 @@ +https://github.polettix.it/ETOOBUSY/2021/07/21/pwc122-average-of-stream/ diff --git a/challenge-122/polettix/blog1.txt b/challenge-122/polettix/blog1.txt new file mode 100644 index 0000000000..af047af7e6 --- /dev/null +++ b/challenge-122/polettix/blog1.txt @@ -0,0 +1 @@ +https://github.polettix.it/ETOOBUSY/2021/07/22/pwc122-basketball-points/ diff --git a/challenge-122/polettix/perl/ch-1.pl b/challenge-122/polettix/perl/ch-1.pl new file mode 100644 index 0000000000..8057dce9a7 --- /dev/null +++ b/challenge-122/polettix/perl/ch-1.pl @@ -0,0 +1,25 @@ +#!/usr/bin/env perl +use v5.24; +use warnings; +use experimental 'signatures'; +no warnings 'experimental::signatures'; + +sub average_of_stream (@items) { + my ($sum, $tsum) = (0, ''); + for my $last (0 .. $#items) { + $sum += $items[$last]; + if (! $last) { + say "Average of first number is $sum."; + $tsum = $sum; + } + else { + my $n = $last + 1; + $tsum = $tsum . '+' . $items[$last]; + my $avg = $sum / $n; + say "Average of first $n numbers ($tsum)/$n = $avg"; + } + } +} + +my @stream = @ARGV ? @ARGV : qw<10 20 30 40 50 60 70 80 90>; +average_of_stream(@stream); diff --git a/challenge-122/polettix/perl/ch-2.pl b/challenge-122/polettix/perl/ch-2.pl new file mode 100644 index 0000000000..bfef6502a6 --- /dev/null +++ b/challenge-122/polettix/perl/ch-2.pl @@ -0,0 +1,102 @@ + +#!/usr/bin/env perl +use v5.24; +use warnings; +use experimental 'signatures'; +no warnings 'experimental::signatures'; + +sub int_sums_iterator ($N, $max = undef) { + if ($N < 1) { + my @retvals = ([]); + return sub { shift @retvals }; + } + $max //= $N; + my $first = $N < $max ? $N : $max; + my $rit = undef; + return sub { + my @retval; + while ($first > 0) { + $rit //= int_sums_iterator($N - $first, $first); + if (my $rest = $rit->()) { + return [$first, $rest->@*]; + } + ($first, $rit) = ($first - 1, undef); + } + return; + } +} + +sub permutations_iterator { + my %args = (@_ && ref($_[0])) ? %{$_[0]} : @_; + my $items = $args{items} || die "invalid or missing parameter 'items'"; + my $filter = $args{filter} || sub { wantarray ? @_ : [@_] }; + my @indexes = 0 .. $#$items; + my @stack = (0) x @indexes; + my $sp = undef; + return sub { + if (! defined $sp) { $sp = 0 } + else { + while ($sp < @indexes) { + if ($stack[$sp] < $sp) { + my $other = $sp % 2 ? $stack[$sp] : 0; + @indexes[$sp, $other] = @indexes[$other, $sp]; + $stack[$sp]++; + $sp = 0; + last; + } + else { + $stack[$sp++] = 0; + } + } + } + return $filter->(@{$items}[@indexes]) if $sp < @indexes; + return; + } +} + +sub basketball_points ($S) { + # $isi keeps track of iterating through all partitions of the + # input integer $S with 1, 2, or 3 + my $isi = int_sums_iterator($S, 3); + + # $pi allows iterating through all partitions of a specific + # partition of $S. %seen allows filtering out duplicates. + my ($pi, %seen); + + return sub { + while ('necessary') { + if (!$pi) { # no more permutations? Start next cycle + # if $isi->() does not return anything meaningful, we + # exhausted the partitions of $S and can stop here. + my $arrangement = $isi->() or return; + + # otherwise, $pi will help us move through the + # permutations + $pi = permutations_iterator(items => $arrangement); + %seen = (); + } + if (my @candidate = $pi->()) { + # %seen is used to filter out duplicates. As a hash, it + # is indexed via a string, which is $key in our case + my $key = join ' ', @candidate; + return @candidate unless $seen{$key}++; + + # if $seen[$key} was already greater than 0 we arrive here. + # The external loop "while ('necessary')..." takes care + # to move on to the next candidate + } + else { + # we arrive here if the permutations iterator is exhausted. + # We set $pi to undef, so that the test at the beginning + # of the loop will generate a new permutations iterator. + $pi = undef; + } + } + }; +} + +my $total = shift || 5; +my $bp = basketball_points($total); +while (my @s = $bp->()) { + say join ' ', @s; +} diff --git a/challenge-122/polettix/raku/ch-1.raku b/challenge-122/polettix/raku/ch-1.raku new file mode 100644 index 0000000000..ae64a17bce --- /dev/null +++ b/challenge-122/polettix/raku/ch-1.raku @@ -0,0 +1,21 @@ +#!/usr/bin/env raku +use v6; + +sub average-of-stream (@items) { + my ($sum, $tsum) = (0, ''); + for 0 .. @items.end -> $last { + $sum += @items[$last]; + if (! $last) { + put "Average of first number is $sum."; + $tsum = $sum; + } + else { + my $n = $last + 1; + $tsum = $tsum ~ '+' ~ @items[$last]; + put "Average of first $n numbers ($tsum)/$n = {{ $sum / $n }}"; + } + } +} + +my @stream = @*ARGS ?? @*ARGS !! <10 20 30 40 50 60 70 80 90>; +average-of-stream(@stream); diff --git a/challenge-122/polettix/raku/ch-2.raku b/challenge-122/polettix/raku/ch-2.raku new file mode 100644 index 0000000000..e3ecd5169d --- /dev/null +++ b/challenge-122/polettix/raku/ch-2.raku @@ -0,0 +1,48 @@ +#!/usr/bin/env raku +use v6; + +sub int-sums-iterator (Int:D $N, Int :$max) { + if ($N < 1) { + my @retvals = $[]; + return sub { @retvals.shift }; + } + $max //= $N; + my $first = $N < $max ?? $N !! $max; + my $rit; + return sub { + my @retval; + while ($first > 0) { + $rit //= int-sums-iterator($N - $first, max => $first); + if (defined(my $rest = $rit())) { + return [$first, |$rest]; + } + ($first, $rit) = ($first - 1); + } + return; + } +} + +sub basketball-points ($S) { + my $isi = int-sums-iterator($S, max => 3); + my (@ps, %seen); + return sub { + loop { + if ! @ps { + defined(my $cmb = $isi()) or return; + @ps = permutations($cmb); + %seen = (); + } + if @ps { + my @candidate = @ps.shift; + my $key = @candidate.join: ' '; + return |@candidate unless %seen{$key}++; + } + } + } +} + +my $n = @*ARGS ?? @*ARGS[0] !! 5; +my $bp = basketball-points($n); +while $bp() -> $cmb { + $cmb.join(' ').put; +} |
