diff options
| author | Dave Jacoby <jacoby.david@gmail.com> | 2025-02-06 21:06:46 -0500 |
|---|---|---|
| committer | Dave Jacoby <jacoby.david@gmail.com> | 2025-02-06 21:06:46 -0500 |
| commit | c504cdab4acc696ebcd16f0e411c7b75b61f23f7 (patch) | |
| tree | 773432eae4a336232654632e871b46153ca39d49 /challenge-306 | |
| parent | b1beb66bad02cf5c1bb1793c4590acb062b17298 (diff) | |
| parent | ea528b3a4f9f371f274a0c9c3012f49cb5e2bed0 (diff) | |
| download | perlweeklychallenge-club-c504cdab4acc696ebcd16f0e411c7b75b61f23f7.tar.gz perlweeklychallenge-club-c504cdab4acc696ebcd16f0e411c7b75b61f23f7.tar.bz2 perlweeklychallenge-club-c504cdab4acc696ebcd16f0e411c7b75b61f23f7.zip | |
Merge branch 'master' of https://github.com/manwar/perlweeklychallenge-club
Diffstat (limited to 'challenge-306')
39 files changed, 1892 insertions, 7 deletions
diff --git a/challenge-306/0rir/raku/ch-1.raku b/challenge-306/0rir/raku/ch-1.raku new file mode 100644 index 0000000000..e40bf11f01 --- /dev/null +++ b/challenge-306/0rir/raku/ch-1.raku @@ -0,0 +1,56 @@ +#!/usr/bin/env raku +# :vim ft=raku sw=4 expandtab # 🦋 ∅∪∩∋∈∉⊆ ≡ ≢ « » ∴ +use v6.d; +use Test; + +=begin comment +306-1: Odd Sum Submitted by: Mohammad Sajid Anwar +You are given an array of positive integers, @ints. +Write a script to return the sum of all possible odd-length subarrays of the given array. A subarray is a contiguous subsequence of the array. + +Example 1 +Input: @ints = (2, 5, 3, 6, 4) +Output: 77 + +Odd length sub-arrays: +(2) => 2 +(5) => 5 +(3) => 3 +(6) => 6 +(4) => 4 +(2, 5, 3) => 10 +(5, 3, 6) => 14 +(3, 6, 4) => 13 +(2, 5, 3, 6, 4) => 20 + +Sum => 2 + 5 + 3 + 6 + 4 + 10 + 14 + 13 + 20 => 77 +Example 2 +Input: @ints = (1, 3) +Output: 4 +=end comment + +my @Test = + 77, (2, 5, 3, 6, 4), + 4, (1, 3), + 4, (4,), + 0, (), +; + +plan @Test ÷ 2; + +multi task( [] ) { 0 } +multi task( @a --> Int) { + sum do for 1, *+2 … $ = @a % 2 ?? +@a !! @a -1 { + sum @a.rotor($_ => -$_ +1 ).flat; + } +} + +for @Test -> $exp, @in { + is task( @in), $exp, "{$exp // $exp.^name()} <- @in.raku()" +} +done-testing; + +my @int = (2, 5, 3, 6, 4, 10); +say "\nInput: @int = @int[]\nOutput: ", task( @int); + + diff --git a/challenge-306/0rir/raku/ch-2.raku b/challenge-306/0rir/raku/ch-2.raku new file mode 100644 index 0000000000..360a462676 --- /dev/null +++ b/challenge-306/0rir/raku/ch-2.raku @@ -0,0 +1,87 @@ +#!/usr/bin/env raku +# :vim ft=raku sw=4 expandtab # 🦋 ∅∪∩∋∈∉⊆ ≡ ≢ « » ∴ +use v6.d; +use Test; + +=begin comment +Task 2: Last Element +Submitted by: Mohammad Sajid Anwar +You are given a array of integers, @ints. + +Write a script to play a game where you pick two biggest integers in the given array, say x and y. Then do the following: + +a) if x == y then remove both from the given array +b) if x != y then remove x and replace y with (y - x) +At the end of the game, there is at most one element left. + +Return the last element if found otherwise return 0. + +Example 1 +Input: @ints = (3, 8, 5, 2, 9, 2) +Output: 1 + +Step 1: pick 8 and 9 => (3, 5, 2, 1, 2) +Step 2: pick 3 and 5 => (2, 2, 1, 2) +Step 3: pick 2 and 1 => (1, 2, 2) +Step 4: pick 2 and 1 => (1, 2) +Step 5: pick 1 and 2 => (1) +Example 2 +Input: @ints = (3, 2, 5) +Output: 0 + +Step 1: pick 3 and 5 => (2, 2) +Step 2: pick 2 and 2 => () +=end comment + +=begin comment + Although the game cannot generate a zed, it is a possible ending + value. So I am maintaining the difference between empty and 0. +=end comment + + +my @Test = + Int, ()».Int, + 0, (0,)».Int, + 3, (3,)».Int, + Int, (0,0)».Int, + Int, ( -1, -1)».Int, + 0, (0,0,0)».Int, + Int, (3, 2, 5)».Int, + Int, (3,3,3,3)».Int, + 1, (1,1, 39 ,40)».Int, + 3, (3,3,3,3,3)».Int, + 1, (3, 8, 5, 2, 9, 2)».Int, + 7, (0, 0, 0, 0, 0, 7)».Int, +; +plan @Test ÷ 2; + + +only task( @a --> Int) { + my $h = @a.BagHash; + my Int $max; + my Int $max-jr; + + loop { + return Int if not $h; # Done if empty. + + # Handle the max level. + $max = $h.keys.max; + next if $h{$max} :delete %% 2; + + return $max if not $h; # No next level. + + # Grab next max, delete it, and store the differ𝑒nce. + $max-jr = $h.keys.max; + -- $h{ $max-jr}; + $h.add( $max - $max-jr); + } +} + +for @Test -> $exp, @in { + is task( @in), $exp, "{$exp // $exp.^name()}\t<- @in.raku()" +} +done-testing; + +my Int @int = 3, 8, 5, 2, 9, 1; +say "\nInput: @int = @int[]\nOutput: ", task(@int) // 0; + diff --git a/challenge-306/arne-sommer/blog.txt b/challenge-306/arne-sommer/blog.txt new file mode 100644 index 0000000000..571da8edc5 --- /dev/null +++ b/challenge-306/arne-sommer/blog.txt @@ -0,0 +1 @@ +https://raku-musings.com/elementary-odd.html diff --git a/challenge-306/arne-sommer/raku/ch-1.raku b/challenge-306/arne-sommer/raku/ch-1.raku new file mode 100755 index 0000000000..8b6a3633a5 --- /dev/null +++ b/challenge-306/arne-sommer/raku/ch-1.raku @@ -0,0 +1,22 @@ +#! /usr/bin/env raku + +unit sub MAIN (*@ints where all(@ints) ~~ Int && all(@ints) > 0, + :v(:$verbose)); + +my $end = @ints.end; +my $sum = 0; + +for 0 .. $end -> $start +{ + for $start .. $end -> $stop + { + next unless ($stop - $start) %% 2; + my @slice = @ints[$start .. $stop]; + my $total = @slice.sum; + $sum += $total; + + say ": Slice Indices:$start:$stop Values:({ @slice.join(",") }) Sum:$total Total:$sum" if $verbose; + } +} + +say $sum; diff --git a/challenge-306/arne-sommer/raku/ch-2.raku b/challenge-306/arne-sommer/raku/ch-2.raku new file mode 100755 index 0000000000..8709e83d53 --- /dev/null +++ b/challenge-306/arne-sommer/raku/ch-2.raku @@ -0,0 +1,31 @@ +#! /usr/bin/env raku + +unit sub MAIN (*@ints where all(@ints) ~~ Int, + :v(:$verbose)); + +while @ints.elems >= 2 +{ + my @x-index = @ints.max(:k); + my $x = @ints[@x-index[0]]; + + sink @ints.splice(@x-index[0], 1); + + if @x-index.elems > 1 + { + my @y-index = @ints.max(:k); + sink @ints.splice(@y-index[0], 1); + say ": Removed x:$x and y:$x -> ({ @ints.join(",") })" if $verbose; + } + else + { + my @y-index = @ints.max(:k); + my $y = @ints[@y-index[0]]; + my $replace = $x - $y; + + sink @ints.splice(@y-index[0], 1, $replace); + + say ": Removed x:$x, replaced y:$y with $replace -> ({ @ints.join(",") })" if $verbose; + } +} + +say @ints.elems ?? @ints.head !! 0; diff --git a/challenge-306/arne-sommer/raku/last-element b/challenge-306/arne-sommer/raku/last-element new file mode 100755 index 0000000000..8709e83d53 --- /dev/null +++ b/challenge-306/arne-sommer/raku/last-element @@ -0,0 +1,31 @@ +#! /usr/bin/env raku + +unit sub MAIN (*@ints where all(@ints) ~~ Int, + :v(:$verbose)); + +while @ints.elems >= 2 +{ + my @x-index = @ints.max(:k); + my $x = @ints[@x-index[0]]; + + sink @ints.splice(@x-index[0], 1); + + if @x-index.elems > 1 + { + my @y-index = @ints.max(:k); + sink @ints.splice(@y-index[0], 1); + say ": Removed x:$x and y:$x -> ({ @ints.join(",") })" if $verbose; + } + else + { + my @y-index = @ints.max(:k); + my $y = @ints[@y-index[0]]; + my $replace = $x - $y; + + sink @ints.splice(@y-index[0], 1, $replace); + + say ": Removed x:$x, replaced y:$y with $replace -> ({ @ints.join(",") })" if $verbose; + } +} + +say @ints.elems ?? @ints.head !! 0; diff --git a/challenge-306/arne-sommer/raku/last-element-sort b/challenge-306/arne-sommer/raku/last-element-sort new file mode 100755 index 0000000000..91ba72492d --- /dev/null +++ b/challenge-306/arne-sommer/raku/last-element-sort @@ -0,0 +1,28 @@ +#! /usr/bin/env raku + +unit sub MAIN (*@ints where all(@ints) ~~ Int, + :v(:$verbose)); + +my @sorted = @ints.sort(-*); + +say ":Sorted: { @sorted.join(",") }" if $verbose; + +while @sorted.elems >= 2 +{ + my $y = @sorted.shift; + my $x = @sorted.shift; + + if $x == $y + { + say ":Removed x:$x and y:$y -> ({ @sorted.join(",") })" if $verbose; + } + else + { + my $replace = $y - $x; + @sorted.push: $replace; + @sorted .= sort(-*); + say ":Replaced x:$x and y:$y with $replace -> ({ @sorted.join(",") })" if $verbose; + } +} + +say @sorted.elems ?? @sorted.head !! 0; diff --git a/challenge-306/arne-sommer/raku/odd-sum b/challenge-306/arne-sommer/raku/odd-sum new file mode 100755 index 0000000000..8b6a3633a5 --- /dev/null +++ b/challenge-306/arne-sommer/raku/odd-sum @@ -0,0 +1,22 @@ +#! /usr/bin/env raku + +unit sub MAIN (*@ints where all(@ints) ~~ Int && all(@ints) > 0, + :v(:$verbose)); + +my $end = @ints.end; +my $sum = 0; + +for 0 .. $end -> $start +{ + for $start .. $end -> $stop + { + next unless ($stop - $start) %% 2; + my @slice = @ints[$start .. $stop]; + my $total = @slice.sum; + $sum += $total; + + say ": Slice Indices:$start:$stop Values:({ @slice.join(",") }) Sum:$total Total:$sum" if $verbose; + } +} + +say $sum; diff --git a/challenge-306/athanasius/perl/ch-1.pl b/challenge-306/athanasius/perl/ch-1.pl new file mode 100644 index 0000000000..df583412d8 --- /dev/null +++ b/challenge-306/athanasius/perl/ch-1.pl @@ -0,0 +1,175 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 306 +========================= + +TASK #1 +------- +*Odd Sum* + +Submitted by: Mohammad Sajid Anwar + +You are given an array of positive integers, @ints. + +Write a script to return the sum of all possible odd-length subarrays of the +given array. A subarray is a contiguous subsequence of the array. + +Example 1 + + Input: @ints = (2, 5, 3, 6, 4) + Output: 77 + + Odd length sub-arrays: + (2) => 2 + (5) => 5 + (3) => 3 + (6) => 6 + (4) => 4 + (2, 5, 3) => 10 + (5, 3, 6) => 14 + (3, 6, 4) => 13 + (2, 5, 3, 6, 4) => 20 + + Sum => 2 + 5 + 3 + 6 + 4 + 10 + 14 + 13 + 20 => 77 + +Example 2 + + Input: @ints = (1, 3) + Output: 4 + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2025 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=comment + +Assumption +---------- +A "positive" integer is greater than zero. + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. One or more positive integers are entered on the command-line. + +=cut +#=============================================================================== + +use v5.32; # Enables strictures +use warnings; +use Const::Fast; +use Regexp::Common qw( number ); +use Test::More; + +const my $USAGE => <<END; +Usage: + perl $0 [<ints> ...] + perl $0 + + [<ints> ...] A non-empty list of positive integers +END + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\nChallenge 306, Task #1: Odd Sum (Perl)\n\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + if (scalar @ARGV == 0) + { + run_tests(); + } + else + { + my @ints = @ARGV; + + for (@ints) + { + / ^ $RE{num}{int} $ /x or error( qq["$_" is not a valid integer] ); + $_ > 0 or error( "$_ is not positive"); + } + + printf "Input: \@ints = (%s)\n", join ', ', @ints; + + my $odd_sum = find_odd_sum( \@ints ); + + print "Output: $odd_sum\n"; + } +} + +#------------------------------------------------------------------------------- +sub find_odd_sum +#------------------------------------------------------------------------------- +{ + my ($ints) = @_; + my $odd_sum = 0; + + for my $i (0 .. $#$ints) + { + my $sum = 0; + my $count = 0; + + for my $j ($i .. $#$ints) + { + $sum += $ints->[ $j ]; + $odd_sum += $sum if ++$count % 2; + } + } + + return $odd_sum; +} + +#------------------------------------------------------------------------------- +sub run_tests +#------------------------------------------------------------------------------- +{ + print "Running the test suite\n"; + + while (my $line = <DATA>) + { + chomp $line; + + my ($test_name, $ints_str, $expected) = split / \| /x, $line; + + for ($test_name, $ints_str, $expected) + { + s/ ^ \s+ //x; + s/ \s+ $ //x; + } + + my @ints = split / \s+ /x, $ints_str; + my $odd_sum = find_odd_sum( \@ints ); + + is $odd_sum, $expected, $test_name; + } + + done_testing; +} + +#------------------------------------------------------------------------------- +sub error +#------------------------------------------------------------------------------- +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +################################################################################ + +__DATA__ +Example 1|2 5 3 6 4|77 +Example 2|1 3 | 4 diff --git a/challenge-306/athanasius/perl/ch-2.pl b/challenge-306/athanasius/perl/ch-2.pl new file mode 100644 index 0000000000..e718e40dfd --- /dev/null +++ b/challenge-306/athanasius/perl/ch-2.pl @@ -0,0 +1,178 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 306 +========================= + +TASK #2 +------- +*Last Element* + +Submitted by: Mohammad Sajid Anwar + +You are given a array of integers, @ints. + +Write a script to play a game where you pick two biggest integers in the given +array, say x and y. Then do the following: + + a) if x == y then remove both from the given array + b) if x != y then remove x and replace y with (y - x) + +At the end of the game, there is at most one element left. + +Return the last element if found otherwise return 0. + +Example 1 + + Input: @ints = (3, 8, 5, 2, 9, 2) + Output: 1 + + Step 1: pick 8 and 9 => (3, 5, 2, 1, 2) + Step 2: pick 3 and 5 => (2, 2, 1, 2) + Step 3: pick 2 and 1 => (1, 2, 2) + Step 4: pick 2 and 1 => (1, 2) + Step 5: pick 1 and 2 => (1) + +Example 2 + + Input: @ints = (3, 2, 5) + Output: 0 + + Step 1: pick 3 and 5 => (2, 2) + Step 2: pick 2 and 2 => () + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2025 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=comment + +Assumption +---------- +The input integers are positive (greater than zero). + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. One or more positive integers are entered on the command-line. + +=cut +#=============================================================================== + +use v5.32; # Enables strictures and warnings +use Const::Fast; +use Regexp::Common qw( number ); +use Test::More; + +const my $USAGE => <<END; +Usage: + perl $0 [<ints> ...] + perl $0 + + [<ints> ...] A non-empty list of positive integers +END + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\nChallenge 306, Task #2: Last Element (Perl)\n\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + if (scalar @ARGV == 0) + { + run_tests(); + } + else + { + my @ints = @ARGV; + + for (@ints) + { + / ^ $RE{num}{int} $ /x or error( qq["$_" is not a valid integer] ); + $_ > 0 or error( "$_ is not positive"); + } + + printf "Input: \@ints = (%s)\n", join ', ', @ints; + + my $last_element = find_last_element( \@ints ); + + print "Output: $last_element\n"; + } +} + +#------------------------------------------------------------------------------- +sub find_last_element +#------------------------------------------------------------------------------- +{ + my ($ints) = @_; + my @n = sort { $a <=> $b } @$ints; + + while (scalar @n > 1) + { + my $y = pop @n; + my $x = pop @n; + + if ($y > $x) + { + push @n, $y - $x; + + @n = sort { $a <=> $b } @n; + } + } + + return (scalar @n == 0) ? 0 : $n[ 0 ]; +} + +#------------------------------------------------------------------------------- +sub run_tests +#------------------------------------------------------------------------------- +{ + print "Running the test suite\n"; + + while (my $line = <DATA>) + { + chomp $line; + + my ($test_name, $ints_str, $expected) = split / \| /x, $line; + + for ($test_name, $ints_str, $expected) + { + s/ ^ \s+ //x; + s/ \s+ $ //x; + } + + my @ints = split / \s+ /x, $ints_str; + my $last = find_last_element( \@ints ); + + is $last, $expected, $test_name; + } + + done_testing; +} + +#------------------------------------------------------------------------------- +sub error +#------------------------------------------------------------------------------- +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +################################################################################ + +__DATA__ +Example 1|3 8 5 2 9 2|1 +Example 2|3 2 5 |0 diff --git a/challenge-306/athanasius/raku/ch-1.raku b/challenge-306/athanasius/raku/ch-1.raku new file mode 100644 index 0000000000..7f901f8a0f --- /dev/null +++ b/challenge-306/athanasius/raku/ch-1.raku @@ -0,0 +1,166 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 306 +========================= + +TASK #1 +------- +*Odd Sum* + +Submitted by: Mohammad Sajid Anwar + +You are given an array of positive integers, @ints. + +Write a script to return the sum of all possible odd-length subarrays of the +given array. A subarray is a contiguous subsequence of the array. + +Example 1 + + Input: @ints = (2, 5, 3, 6, 4) + Output: 77 + + Odd length sub-arrays: + (2) => 2 + (5) => 5 + (3) => 3 + (6) => 6 + (4) => 4 + (2, 5, 3) => 10 + (5, 3, 6) => 14 + (3, 6, 4) => 13 + (2, 5, 3, 6, 4) => 20 + + Sum => 2 + 5 + 3 + 6 + 4 + 10 + 14 + 13 + 20 => 77 + +Example 2 + + Input: @ints = (1, 3) + Output: 4 + +=end comment +################################################################################ + +#--------------------------------------# +# Copyright © 2025 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=begin comment + +Assumption +---------- +A "positive" integer is greater than zero. + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. One or more positive integers are entered on the command-line. + +=end comment +#=============================================================================== + +use Test; + +subset Pos of Int where * > 0; + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + "\nChallenge 306, Task #1: Odd Sum (Raku)\n".put; +} + +#=============================================================================== +multi sub MAIN +( + #| A non-empty list of positive integers + + *@ints where { .elems > 0 && .all ~~ Pos:D } +) +#=============================================================================== +{ + "Input: \@ints = (%s)\n".printf: @ints.join: ', '; + + my UInt $odd-sum = find-odd-sum( @ints ); + + "Output: $odd-sum".put; +} + +#=============================================================================== +multi sub MAIN() # No input: run the test suite +#=============================================================================== +{ + run-tests(); +} + +#------------------------------------------------------------------------------- +sub find-odd-sum( List:D[Pos:D] $ints --> UInt:D ) +#------------------------------------------------------------------------------- +{ + my $odd-sum = 0; + + for 0 .. $ints.end -> UInt $i + { + my UInt $sum = 0; + my UInt $count = 0; + + for $i .. $ints.end -> UInt $j + { + $sum += $ints[ $j ]; + $odd-sum += $sum if ++$count % 2; + } + } + + return $odd-sum; +} + +#------------------------------------------------------------------------------- +sub run-tests() +#------------------------------------------------------------------------------- +{ + 'Running the test suite'.put; + + for test-data.lines -> Str $line + { + my Str ($test-name, $ints-str, $expected) = $line.split: / \| /; + + for $test-name, $ints-str, $expected + { |
