diff options
| author | Jared Martin <760765+jaredor@users.noreply.github.com> | 2021-07-25 19:00:51 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-07-25 19:00:51 -0500 |
| commit | daba10705df0818bb62f7a2caee100e37856ed6d (patch) | |
| tree | a4d89b0000ec1c48230283932779db05217dc36f /challenge-122 | |
| parent | 702f6ba67a78b9c9d8c819d5517be691852b9b06 (diff) | |
| parent | 31011089fc9fd0202e6b99f557b311f7ac840495 (diff) | |
| download | perlweeklychallenge-club-daba10705df0818bb62f7a2caee100e37856ed6d.tar.gz perlweeklychallenge-club-daba10705df0818bb62f7a2caee100e37856ed6d.tar.bz2 perlweeklychallenge-club-daba10705df0818bb62f7a2caee100e37856ed6d.zip | |
Merge branch 'manwar:master' into master
Diffstat (limited to 'challenge-122')
| -rw-r--r-- | challenge-122/bruce-gray/perl/ch-1.pl | 32 | ||||
| -rw-r--r-- | challenge-122/bruce-gray/perl/ch-2.pl | 20 | ||||
| -rw-r--r-- | challenge-122/bruce-gray/raku/ch-1.raku | 10 | ||||
| -rw-r--r-- | challenge-122/bruce-gray/raku/ch-2.raku | 18 | ||||
| -rw-r--r-- | challenge-122/colin-crain/perl/ch-1.pl | 56 | ||||
| -rw-r--r-- | challenge-122/colin-crain/perl/ch-2.pl | 96 | ||||
| -rw-r--r-- | challenge-122/colin-crain/raku/ch-1.raku | 93 | ||||
| -rw-r--r-- | challenge-122/colin-crain/raku/ch-2.raku | 64 | ||||
| -rw-r--r-- | challenge-122/pete-houston/awk/ch-1.awk | 17 | ||||
| -rw-r--r-- | challenge-122/pete-houston/perl/ch-1.pl | 24 | ||||
| -rw-r--r-- | challenge-122/pete-houston/perl/ch-2.pl | 75 |
11 files changed, 505 insertions, 0 deletions
diff --git a/challenge-122/bruce-gray/perl/ch-1.pl b/challenge-122/bruce-gray/perl/ch-1.pl new file mode 100644 index 0000000000..70beafbe8f --- /dev/null +++ b/challenge-122/bruce-gray/perl/ch-1.pl @@ -0,0 +1,32 @@ +use strict; +use warnings; +use 5.020; +use experimental qw<signatures>; + +sub make_arithmetic_generator ( $start, $increment ) { + my $last = $start - $increment; + return sub { + return ( $last += $increment ); + }; +} +sub running_average_generator ( $code_for_next_input ) { + my ($sum, $count); + return sub { + return ( $sum += $code_for_next_input->() ) / ++$count; + }; +} + +my $stream_next = make_arithmetic_generator( 10, 10 ); +my $avg_next = running_average_generator( $stream_next ); +my $count_wanted = 20; +while ( defined( my $avg = $avg_next->() ) and $count_wanted-- ) { + say $avg; +} + +# I would have just used this code, +# but the task specifies "stream", not "list" or "array"! +# sub running_average ( @s ) { +# my ( $sum, $count ); +# return map { ($sum += $_) / ++$count } @s; +# } +# say for running_average( map { $_ * 10 } 1..20 ); diff --git a/challenge-122/bruce-gray/perl/ch-2.pl b/challenge-122/bruce-gray/perl/ch-2.pl new file mode 100644 index 0000000000..f537de2105 --- /dev/null +++ b/challenge-122/bruce-gray/perl/ch-2.pl @@ -0,0 +1,20 @@ +use strict; +use warnings; +use 5.024; +use experimental qw<signatures>; + +sub bball_ways ( $S ) { + use constant SHOT_VALUES => [ 1, 2, 3 ]; + return [] if $S == 0; + return if $S < 0; + + my @ret; + + for my $n ( SHOT_VALUES->@* ) { + push @ret, map [ $n, @{$_} ], bball_ways($S - $n); + } + + return @ret; +} + +say join(' ', @{$_}) for bball_ways( $ARGV[0] ); diff --git a/challenge-122/bruce-gray/raku/ch-1.raku b/challenge-122/bruce-gray/raku/ch-1.raku new file mode 100644 index 0000000000..a96e47f57b --- /dev/null +++ b/challenge-122/bruce-gray/raku/ch-1.raku @@ -0,0 +1,10 @@ +# sub ra { ( [\+] @^s ) Z/ ( 1 .. * ) } + +sub running_average ( @s ) { + constant @running_count = 1 .. *; + my @running_sum = [\+] @s; + + return @running_sum Z/ @running_count; +} + +put running_average( 10, 20 … * ).head(25); diff --git a/challenge-122/bruce-gray/raku/ch-2.raku b/challenge-122/bruce-gray/raku/ch-2.raku new file mode 100644 index 0000000000..e424a47ade --- /dev/null +++ b/challenge-122/bruce-gray/raku/ch-2.raku @@ -0,0 +1,18 @@ +sub b'ball-ways ( UInt:D $S ) { + constant @SHOT_VALUES = 1, 2, 3; + return if $S == 0; + + return gather for @SHOT_VALUES -> $n { + next if $S - $n < 0; + + if b'ball-ways($S - $n) -> @ways { + take ($n, |.list) for @ways; + } + else { + take ($n,); + } + } +} + +unit sub MAIN ( UInt:D $final_score ); +.put for b'ball-ways( $final_score ); diff --git a/challenge-122/colin-crain/perl/ch-1.pl b/challenge-122/colin-crain/perl/ch-1.pl new file mode 100644 index 0000000000..60fac24fe2 --- /dev/null +++ b/challenge-122/colin-crain/perl/ch-1.pl @@ -0,0 +1,56 @@ +#!/Users/colincrain/perl5/perlbrew/perls/perl-5.32.0/bin/perl
+#
+# crossing-the-stream.pl
+#
+# Average of Stream
+# Submitted by: Mohammad S Anwar
+# You are given a stream of numbers, @N.
+#
+# Write a script to print the average of the stream at every point.
+#
+# Example
+# Input: @N = (10, 20, 30, 40, 50, 60, 70, 80, 90, ...)
+# Output: 10, 15, 20, 25, 30, 35, 40, 45, 50, ...
+#
+# Average of first number is 10.
+# Average of first 2 numbers (10+20)/2 = 15
+# Average of first 3 numbers (10+20+30)/3 = 20
+# Average of first 4 numbers (10+20+30+40)/4 = 25 and so on.
+#
+# method:
+# Rather than maintain a separate count of the values summed to
+# create an average, we already have this value as we're always
+# counting elements fron the first index.
+#
+# By calling `each` on the `@stream` array we get tuples of index
+# and value for each element. We establish a running `$sum` value
+# that is kept up-to-date with even new element, dividing this by
+# `$idx`, which always contains one less than the number of elements
+# summed will give us an average value of everything seen up to that
+# point from index 0.
+#
+#
+#
+# © 2021 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+use warnings;
+use strict;
+use utf8;
+use feature ":5.26";
+use feature qw(signatures);
+no warnings 'experimental::signatures';
+
+
+
+my @stream = (10, 20, 30, 40, 50, 60, 70, 80, 90);
+
+my $sum = 0;
+while ( my ($idx, $val) = each @stream ) {
+ $sum += $val;
+ $_ = sprintf "%.2f", $sum / ($idx+1);
+ s/\.0*$//;
+ say "average of first ", $idx+1, " numbers is ", $_;
+}
diff --git a/challenge-122/colin-crain/perl/ch-2.pl b/challenge-122/colin-crain/perl/ch-2.pl new file mode 100644 index 0000000000..2c07bb1cc2 --- /dev/null +++ b/challenge-122/colin-crain/perl/ch-2.pl @@ -0,0 +1,96 @@ +#!/Users/colincrain/perl5/perlbrew/perls/perl-5.32.0/bin/perl
+#
+# trip-from-the-line.pl
+#
+# Basketball Points
+# Submitted by: Mohammad S Anwar
+# You are given a score $S.
+#
+# You can win basketball points e.g. 1 point, 2 points and 3 points.
+#
+# Write a script to find out the different ways you can score $S.
+#
+# Example
+#
+# Input: $S = 4
+# Output: 1 1 1 1
+# 1 1 2
+# 1 2 1
+# 1 3
+# 2 1 1
+# 2 2
+# 3 1
+#
+# Input: $S = 5
+# Output: 1 1 1 1 1
+# 1 1 1 2
+# 1 1 2 1
+# 1 1 3
+# 1 2 1 1
+# 1 2 2
+# 1 3 1
+# 2 1 1 1
+# 2 1 2
+# 2 2 1
+# 2 3
+# 3 1 1
+# 3 2
+#
+# method:
+# what we have here is an integer partition problem, of sorts,
+# where we only allow the partitions the maximum value of 3. The
+# way I thought up to do this, out on a walk, was to start with
+# an empty list of lists, and add lists of partial partitions to
+# it as long as the sum was less than the final score. We would
+# work through this list, shifting off the next partial from one
+# end, adding either a new 1, 2 or 3 to the end of it and if the
+# new instance still summed less than the total, pushing it on
+# the backside of the queue to come around again. If the sum
+# came out exact, we have a parition and that list is moved over to
+# another list for solutions and not recycled.
+#
+# The first time around I put in a clause, that a new number
+# cannot be less than the last number placed: this avoids
+# repetitions by keeping the new patterns ordered, and we wont
+# get both [1, 2, 1, 2] and [2, 1, 2, 1].
+#
+# After I got this up and running I realized that what was being
+# requested in fact wanted these repetitions counted as separate
+# variations. So be it; this only involved stripping out a
+# single `grep` filtering the `@points` options, so at each
+# juncture the full gamut of adding a new 1, 2 or 3 was
+# considered.
+#
+# © 2021 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+use warnings;
+use strict;
+use utf8;
+use feature ":5.26";
+use feature qw(signatures);
+no warnings 'experimental::signatures';
+use List::Util qw( sum );
+
+my $score = shift @ARGV // 5 ; ## default value
+
+my @points = ( 1, 2, 3 );
+
+my @queue = map { [$_] } grep { $_ <= $score } (1..3);
+my @parts;
+
+while ( my $seq = shift @queue ) {
+ for my $next ( @points ) {
+ my $sum = sum $seq->@*, $next;
+ if ( $sum <= $score ) {
+ $sum == $score ? push @parts, [$seq->@*, $next]
+ : push @queue, [$seq->@*, $next] ;
+ }
+ }
+}
+
+say "$_->@*" for @parts;
+
+
diff --git a/challenge-122/colin-crain/raku/ch-1.raku b/challenge-122/colin-crain/raku/ch-1.raku new file mode 100644 index 0000000000..4e415f3d49 --- /dev/null +++ b/challenge-122/colin-crain/raku/ch-1.raku @@ -0,0 +1,93 @@ +#!/usr/bin/env perl6 +# +# +# crossing-the-stream.raku +# +# Average of Stream +# Submitted by: Mohammad S Anwar +# You are given a stream of numbers, @N. +# +# Write a script to print the average of the stream at every point. +# +# Example +# Input: @N = (10, 20, 30, 40, 50, 60, 70, 80, 90, ...) +# Output: 10, 15, 20, 25, 30, 35, 40, 45, 50, ... +# +# Average of first number is 10. +# Average of first 2 numbers (10+20)/2 = 15 +# Average of first 3 numbers (10+20+30)/3 = 20 +# Average of first 4 numbers (10+20+30+40)/4 = 25 and so on. +# +# method: +# Rather than maintain a separate count of the values summed to +# create an average, we already have this value as we're always +# counting elements fron the first index. +# +# By calling `each` on the `@stream` array we get tuples of index +# and value for each element. We establish a running `$sum` value +# that is kept up-to-date with even new element, dividing this by +# `$idx`, which always contains one less than the number of elements +# summed will give us an average value of everything seen up to that +# point from index 0. +# +# +# +# +# © 2021 colin crain +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + + +## using a FIFO queue on a fixed array + +# unit sub MAIN ( *@stream ) ; +# +# @stream.elems == 0 && @stream = (1..1).map: * × 10; +# +# say @stream.WHAT; +# my $sum; +# for @stream.kv -> $idx, $val { +# $sum += $val; +# given sprintf $sum/($idx+1) { +# s/ \.0* $//; +# say "average of first ", $idx+1, " numbers is ", $_; +# } +# } + +## processing a simulated data stream asynchronously + +unit sub MAIN () ; + +my $stream = Channel.new; +my $i; +my $sum; + +my $p = start { + say "stream started. Enter any value to exit"; + + react { + whenever $stream { + done() if $_ !~~ /\d ** 2..* /; + $sum += $_; + $i++; + say "received value $_ from stream, cumulative average now {$sum/$i}"; + } + } + exit; +} + +start { + await $*IN.getc.map: -> $c { + start { + $stream.send( $c ); + } + } +} + +await Supply.interval(1).map: -> $r { + start { + $stream.send(($r+1)*10); + } +} + +$stream.close; +await $p; diff --git a/challenge-122/colin-crain/raku/ch-2.raku b/challenge-122/colin-crain/raku/ch-2.raku new file mode 100644 index 0000000000..d13636d3fc --- /dev/null +++ b/challenge-122/colin-crain/raku/ch-2.raku @@ -0,0 +1,64 @@ +#!/usr/bin/env perl6 +# +# +# trip-from-the-line.raku +# +# Basketball Points +# Submitted by: Mohammad S Anwar +# You are given a score $S. +# +# You can win basketball points e.g. 1 point, 2 points and 3 points. +# +# Write a script to find out the different ways you can score $S. +# +# Example +# +# Input: $S = 4 +# Output: 1 1 1 1 +# 1 1 2 +# 1 2 1 +# 1 3 +# 2 1 1 +# 2 2 +# 3 1 +# +# Input: $S = 5 +# Output: 1 1 1 1 1 +# 1 1 1 2 +# 1 1 2 1 +# 1 1 3 +# 1 2 1 1 +# 1 2 2 +# 1 3 1 +# 2 1 1 1 +# 2 1 2 +# 2 2 1 +# 2 3 +# 3 1 1 +# 3 2 +# +# +# +# © 2021 colin crain +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + + + +unit sub MAIN (Int $score = 5) ; + +my @points = 1, 2, 3 ; +my @queue = @points.grep( * <= $score ) + .map( *.Array ) ; +my @parts; + +while @queue.shift -> @seq { + for @points { + my @new = |@seq, $_ ; + next if @new.sum > $score; + @new.sum == $score ?? @parts.push: @new + !! @queue.push: @new; + } +} + +put $_ for @parts; + diff --git a/challenge-122/pete-houston/awk/ch-1.awk b/challenge-122/pete-houston/awk/ch-1.awk new file mode 100644 index 0000000000..2d4ecf2fff --- /dev/null +++ b/challenge-122/pete-houston/awk/ch-1.awk @@ -0,0 +1,17 @@ +#!/usr/bin/gawk -f
+#===============================================================================
+#
+# FILE: 12201.awk
+#
+# USAGE: ./12201.awk < INFILE
+#
+# DESCRIPTION: Stream average - output the average of all numbers so
+# far as a list.
+#
+# NOTES: Expects each number as the first field on the line
+# AUTHOR: Pete Houston (pete), cpan@openstrike.co.uk
+# ORGANIZATION: Openstrike
+# VERSION: 1.0
+# CREATED: 19/07/21
+#===============================================================================
+{ sum += $1; num++; print sum / num }
diff --git a/challenge-122/pete-houston/perl/ch-1.pl b/challenge-122/pete-houston/perl/ch-1.pl new file mode 100644 index 0000000000..6c01e31795 --- /dev/null +++ b/challenge-122/pete-houston/perl/ch-1.pl @@ -0,0 +1,24 @@ +#!/usr/bin/env perl +#=============================================================================== +# +# FILE: 12201.pl +# +# USAGE: ./12201.pl N N [ N ] ... +# +# DESCRIPTION: Stream average - output the average of all numbers so +# far as a list. +# +# AUTHOR: Pete Houston (pete), cpan@openstrike.co.uk +# ORGANIZATION: Openstrike +# VERSION: 1.0 +# CREATED: 19/07/21 +#=============================================================================== + +use strict; +use warnings; + +my $sum = 0; +my $num = 1; + +my @avg = map { $sum += $_; $sum/$num++ } @ARGV; +print "@avg\n"; diff --git a/challenge-122/pete-houston/perl/ch-2.pl b/challenge-122/pete-houston/perl/ch-2.pl new file mode 100644 index 0000000000..ce94b44fb6 --- /dev/null +++ b/challenge-122/pete-houston/perl/ch-2.pl @@ -0,0 +1,75 @@ +#!/usr/bin/env perl +#=============================================================================== +# +# FILE: 12202.pl +# +# USAGE: ./12202.pl N +# +# DESCRIPTION: Print all permutations of 1, 2, 3 to sum to N. +# +# REQUIREMENTS: Algorithm::Knapsack, List::Util, Math::Combinatorics +# NOTES: Although this works, it is inelegant. +# AUTHOR: Pete Houston (pete), cpan@openstrike.co.uk +# ORGANIZATION: Openstrike +# VERSION: 1.0 +# CREATED: 19/07/21 +#=============================================================================== + +use strict; +use warnings; +use Algorithm::Knapsack; +use List::Util 'sum'; +use Math::Combinatorics; + +my $n = shift; + +my @aoa = combos ($n, 0); +@aoa = permos (@aoa); +for my $set (@aoa) { + print "@$set\n"; +} + +sub combos { + my ($tot, $level) = @_; + my @solutions; + my @scores; + my @fs; + push @scores, ($_) x ($tot / $_) for 1 .. 3; + my $sack = Algorithm::Knapsack->new ( + capacity => $tot, + weights => \@scores, + ); + $sack->compute; + my $combos = 0; + my %seen; + for my $fit ($sack->solutions) { + next unless sum (@scores[@$fit]) == $tot; + my $res = join (' + ', @scores[@$fit]) . " = $tot\n"; + next if $seen{$res}; + $seen{$res} = 1; + # Count frequencies + my %freqs; + $freqs{$_}++ for @scores[@$fit]; + push @fs, [map { $freqs{$_} || 0 } 1 .. 3]; + push @solutions, [@scores[@$fit]]; + $combos++; + } + return @fs; +} + +sub permos { + my @sets = @_; + my @perms; + for my $combo (@sets) { + # Permute these indistinguishably + my $permer = Math::Combinatorics->new ( + count => sum (@$combo), + data => [1 .. 3], + frequency => $combo + ); + while (my @x = $permer->next_string) { + push @perms, [@x]; + } + } + return @perms; +} |
