From c3a196220e1835e6987bdcdae6e896459e6b218f Mon Sep 17 00:00:00 2001 From: Bob Lied Date: Mon, 22 Jan 2024 09:33:14 -0600 Subject: Week 253 solutions --- challenge-253/bob-lied/README | 6 +-- challenge-253/bob-lied/perl/ch-1.pl | 50 +++++++++++++++++++++++++ challenge-253/bob-lied/perl/ch-2.pl | 73 +++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 challenge-253/bob-lied/perl/ch-1.pl create mode 100644 challenge-253/bob-lied/perl/ch-2.pl diff --git a/challenge-253/bob-lied/README b/challenge-253/bob-lied/README index 8b958edfe8..af6f9a022d 100644 --- a/challenge-253/bob-lied/README +++ b/challenge-253/bob-lied/README @@ -1,4 +1,4 @@ -Solutions to weekly challenge 252 by Bob Lied +Solutions to weekly challenge 253 by Bob Lied -https://perlweeklychallenge.org/blog/perl-weekly-challenge-252/ -https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-252/bob-lied +https://perlweeklychallenge.org/blog/perl-weekly-challenge-253/ +https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-253/bob-lied diff --git a/challenge-253/bob-lied/perl/ch-1.pl b/challenge-253/bob-lied/perl/ch-1.pl new file mode 100644 index 0000000000..6144e22dbf --- /dev/null +++ b/challenge-253/bob-lied/perl/ch-1.pl @@ -0,0 +1,50 @@ +#!/usr/bin/env perl +# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu: +#============================================================================= +# Copyright (c) 2024, Bob Lied +#============================================================================= +# ch-1.pl Perl Weekly Challenge 253 Task 1 Split Strings +#============================================================================= +# You are given an array of strings and a character separator. +# Write a script to return all words separated by the given character +# excluding empty string. +# Example 1 Input: @words = ("one.two.three","four.five","six") $separator = "." +# Output: "one","two","three","four","five","six" +# Example 2 Input: @words = ("$perl$$", "$$raku$") $separator = "$" +# Output: "perl","raku" +#============================================================================= + +use v5.38; + +use builtin qw/true false/; no warnings "experimental::builtin"; + +use Getopt::Long; +my $Verbose = 0; +my $DoTest = 0; +my $Separator = " "; + +GetOptions("test" => \$DoTest, "verbose" => \$Verbose, "sep:s" => \$Separator); +exit(!runTest()) if $DoTest; + +say join ",", map { qq("$_") } splitStrings(\@ARGV, $Separator)->@*; + +sub splitStrings($words, $separator) +{ + my @output = grep !/\A\Z/, map { split /\Q$separator\E+/, $_ } $words->@*; + return \@output; +} + +sub runTest +{ + use Test2::V0; + + is( splitStrings( ["one.two.three", "four.five", "six" ], "." ), + [ qw(one two three four five six) ], "Example 1"); + is( splitStrings( [ '$perl$$', '$$raku$' ], '$' ), + [ qw( perl raku ) ], "Example 1"); + + is( splitStrings( [ qw(a b c) ], '/' ), [ qw(a b c) ], "No separator"); + is( splitStrings( [ "////", "//", "/", ], "/" ), [ ], "No words"); + + done_testing; +} diff --git a/challenge-253/bob-lied/perl/ch-2.pl b/challenge-253/bob-lied/perl/ch-2.pl new file mode 100644 index 0000000000..23151598e2 --- /dev/null +++ b/challenge-253/bob-lied/perl/ch-2.pl @@ -0,0 +1,73 @@ +#!/usr/bin/env perl +# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu: +#============================================================================= +# Copyright (c) 2024, Bob Lied +#============================================================================= +# ch-2.pl Perl Weekly Challenge 253 Task 2 Weakest Row +#============================================================================= +# You are given an m x n binary matrix, i.e. only 0 and 1, +# where 1 always appear before 0. +# A row i is weaker than a row j if one of the following is true: +# a) The number of 1s in row i is less than the number of 1s in row j. +# b) Both rows have the same number of 1 and i < j. +# Write a script to return the order of rows from weakest to strongest. +# Example 1 Input: $matrix = [ [1, 1, 0, 0, 0], +# [1, 1, 1, 1, 0], +# [1, 0, 0, 0, 0], +# [1, 1, 0, 0, 0], +# [1, 1, 1, 1, 1] ] +# Output: (2, 0, 3, 1, 4) +# Example 2 Input: $matrix = [ [1, 0, 0, 0], +# [1, 1, 1, 1], +# [1, 0, 0, 0], +# [1, 0, 0, 0] ] +# Output: (0, 2, 3, 1) +#============================================================================= + +use v5.38; + +use builtin qw/trim/; no warnings "experimental::builtin"; +use List::Util qw/sum/; + +use Getopt::Long; +my $Verbose = 0; +my $DoTest = 0; + +GetOptions("test" => \$DoTest, "verbose" => \$Verbose); +exit(!runTest()) if $DoTest; + +# USAGE: give rows as strings on command line, e.g. +# ./ch-1.pl "[1,0,0]" "[0,1,0]" "[0,0,1]" +# ./ch-1.pl 1,0,0 0,1,0 0,0,1 +my @r = map { trim($_) } map { (s/[^01]+/ /gr) } @ARGV; +say join "|", @r if $Verbose; +my @matrix = map { [ split ' ', $_ ] } @r; +say "(", join(", ", weakestRow(\@matrix)->@*), ")"; + +sub weakestRow($m) +{ + my @strength = map { sum $_->@* } $m->@*; + + return [ sort { $strength[$a] <=> $strength[$b] || $a <=> $b } 0 .. $m->$#* ]; +} + +sub runTest +{ + use Test2::V0; + + my $matrix; + $matrix = [ [1, 1, 0, 0, 0], + [1, 1, 1, 1, 0], + [1, 0, 0, 0, 0], + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 1] ]; + is(weakestRow($matrix), [ 2,0,3,1,4 ], "Example 1"); + + $matrix = [ [1, 0, 0, 0], + [1, 1, 1, 1], + [1, 0, 0, 0], + [1, 0, 0, 0] ]; + is(weakestRow($matrix), [ 0,2,3,1 ], "Example 2"); + + done_testing; +} -- cgit From fd73abc34742f832a5b563278987a8ced203913e Mon Sep 17 00:00:00 2001 From: "E. Choroba" Date: Mon, 22 Jan 2024 23:48:32 +0100 Subject: Add solutions to 253: Split Strings & Weakest Row by E. Choroba --- challenge-253/e-choroba/perl/ch-1.pl | 19 +++++++++ challenge-253/e-choroba/perl/ch-2.pl | 80 ++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100755 challenge-253/e-choroba/perl/ch-1.pl create mode 100755 challenge-253/e-choroba/perl/ch-2.pl diff --git a/challenge-253/e-choroba/perl/ch-1.pl b/challenge-253/e-choroba/perl/ch-1.pl new file mode 100755 index 0000000000..abde8f46e2 --- /dev/null +++ b/challenge-253/e-choroba/perl/ch-1.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl +use warnings; +use strict; +use experimental qw( signatures ); + +sub split_strings($separator, @words) { + return [grep length, map split(/\Q$separator/), @words] +} + +use Test2::V0; +plan 2; + +is split_strings('.', 'one.two.three','four.five','six'), + ['one', 'two', 'three', 'four', 'five', 'six'], + 'Example 1'; + +is split_strings('$', '$perl$$', '$$raku$'), + ['perl', 'raku'], + 'Example 2'; diff --git a/challenge-253/e-choroba/perl/ch-2.pl b/challenge-253/e-choroba/perl/ch-2.pl new file mode 100755 index 0000000000..2c3dd8fbab --- /dev/null +++ b/challenge-253/e-choroba/perl/ch-2.pl @@ -0,0 +1,80 @@ +#!/usr/bin/perl +use warnings; +use strict; +use experimental qw( signatures ); + +use List::Util qw{ first }; + +sub weakest_row($matrix) { + return [ + map $_->[0], + sort { $a->[1] <=> $b->[1] || $a->[0] <=> $b->[0] } + map [$_, scalar grep $_, @{ $matrix->[$_] }], + 0 .. $#$matrix + ] +} + +sub weakest_row_grep($matrix) { + return [sort { + grep($_, @{ $matrix->[$a] }) <=> grep($_, @{ $matrix->[$b] }) + || $a <=> $b + } 0 .. $#$matrix] +} + +sub weakest_row_first_schwartzian($matrix) { + return [ + map $_->[0], + sort { $a->[1] <=> $b->[1] || $a->[0] <=> $b->[0] } + map { my $r = $_; + [$r, + (first { ! $matrix->[$r][$_] } 0 .. @{ $matrix->[$r] }) + ] # We're using @, not $#, to prevent undef for all ones. + } 0 .. $#$matrix + ] +} + +use Test2::V0; +plan 3 * 3; + +my $SIZE = 500; + +my $m = [map { my $o = int rand $SIZE; + [(1) x $o, (0) x ($SIZE - $o)] + } 1 .. $SIZE]; + +for my $f (\&weakest_row, + \&weakest_row_grep, + \&weakest_row_first_schwartzian, +) { + is $f->([ + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 0], + [1, 0, 0, 0, 0], + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 1] + ]), [2, 0, 3, 1, 4], 'Example 1'; + + is $f->([ + [1, 0, 0, 0], + [1, 1, 1, 1], + [1, 0, 0, 0], + [1, 0, 0, 0] + ]), [0, 2, 3, 1], 'Example 2'; + + is $f->($m), weakest_row_grep($m), 'same'; +} + +use Benchmark qw{ cmpthese }; + +cmpthese(-5, { + schwartzian => sub { weakest_row($m) }, + grep => sub { weakest_row_grep($m) }, + first_schwartz => sub { weakest_row_first_schwartzian($m) } +}); + + +__END__ + Rate grep first_schwartz schwartzian +grep 9.22/s -- -89% -93% +first_schwartz 84.3/s 814% -- -34% +schwartzian 128/s 1284% 51% -- -- cgit From c24409b0609daed2918cf56465ce398ffbfae68e Mon Sep 17 00:00:00 2001 From: Dave Jacoby Date: Mon, 22 Jan 2024 18:10:09 -0500 Subject: DAJ #253 Blogged --- challenge-253/dave-jacoby/blog.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 challenge-253/dave-jacoby/blog.txt diff --git a/challenge-253/dave-jacoby/blog.txt b/challenge-253/dave-jacoby/blog.txt new file mode 100644 index 0000000000..cd0850d0e7 --- /dev/null +++ b/challenge-253/dave-jacoby/blog.txt @@ -0,0 +1 @@ +https://jacoby.github.io/2024/01/22/split-string-soup-weekly-challenge-253.html -- cgit From dc5ea1c421b80ccfce6db7afc53a5c4f2d47c12a Mon Sep 17 00:00:00 2001 From: robbie-hatley Date: Mon, 22 Jan 2024 18:07:51 -0800 Subject: Robbie Hatley's Perl solutions for The Weekly Challenge #253. --- challenge-253/robbie-hatley/blog.txt | 1 + challenge-253/robbie-hatley/perl/ch-1.pl | 111 +++++++++++++++++++++++ challenge-253/robbie-hatley/perl/ch-2.pl | 145 +++++++++++++++++++++++++++++++ 3 files changed, 257 insertions(+) create mode 100644 challenge-253/robbie-hatley/blog.txt create mode 100755 challenge-253/robbie-hatley/perl/ch-1.pl create mode 100755 challenge-253/robbie-hatley/perl/ch-2.pl diff --git a/challenge-253/robbie-hatley/blog.txt b/challenge-253/robbie-hatley/blog.txt new file mode 100644 index 0000000000..690ce25ec1 --- /dev/null +++ b/challenge-253/robbie-hatley/blog.txt @@ -0,0 +1 @@ +https://hatley-software.blogspot.com/2024/01/robbie-hatleys-solutions-to-weekly_22.html \ No newline at end of file diff --git a/challenge-253/robbie-hatley/perl/ch-1.pl b/challenge-253/robbie-hatley/perl/ch-1.pl new file mode 100755 index 0000000000..d3a70c2eb5 --- /dev/null +++ b/challenge-253/robbie-hatley/perl/ch-1.pl @@ -0,0 +1,111 @@ +#!/usr/bin/env -S perl -CSDA + +=pod + +-------------------------------------------------------------------------------------------------------------- +COLOPHON: +This is a 110-character-wide Unicode UTF-8 Perl-source-code text file with hard Unix line breaks ("\x0A"). +¡Hablo Español! Говорю Русский. Björt skjöldur. ॐ नमो भगवते वासुदेवाय. 看的星星,知道你是爱。麦藁雪、富士川町、山梨県。 + +-------------------------------------------------------------------------------------------------------------- +TITLE BLOCK: +Solutions in Perl for The Weekly Challenge 253-1. +Written by Robbie Hatley on Mon Jan 22, 2023. + +-------------------------------------------------------------------------------------------------------------- +PROBLEM DESCRIPTION: +Task 253-1: Split Strings +Submitted by: Mohammad S Anwar +You are given an array of strings and a character separator. +Write a script to return all words separated by the given +character excluding empty string. + +Example 1: +Input: @words = ("one.two.three","four.five","six") + $separator = "." +Output: "one","two","three","four","five","six" + +Example 2: +Input: @words = ("$perl$$", "$$raku$") + $separator = "$" +Output: "perl","raku" + +-------------------------------------------------------------------------------------------------------------- +PROBLEM NOTES: +This is just a matter of splitting strings based on the given separator, then dumping the empty strings. +One complicating factor, though, is that for separators such as the "." and "$" given in the examples to +actually work, they must be stripped of their magical "meta" powers by using the "\Q" de-meta operator. +So something like this sub should work: +sub split_strings ($separator, @array) { + return grep {length($_)>0} map {split /\Q$separator\E/, $_} @array; +} + +-------------------------------------------------------------------------------------------------------------- +IO NOTES: +Input is via either built-in variables or via @ARGV. If using @ARGV, provide one argument which must be a +single-quoted array of arrays of double-quoted strings, apostrophes escaped as '"'"', with the last element +of each inner array being construed as a "separator", in proper Perl syntax, like so: +./ch-1.pl '(["He shaved?", "She ate dogs.", " "],["didn'"'"'t bathe", "hadn'"'"'t eaten", "'"'"'"])' + +Output is to STDOUT and will be each input followed by the corresponding output. + +=cut + +# ------------------------------------------------------------------------------------------------------------ +# PRAGMAS AND MODULES USED: + +use v5.38; +use strict; +use warnings; +use utf8; +use warnings FATAL => 'utf8'; +use Sys::Binmode; +use Time::HiRes 'time'; + +# ------------------------------------------------------------------------------------------------------------ +# GLOBAL VARIABLES: +our $t0 ; # Seconds since 00:00:00 on Thu Jan 1, 1970. +our $db = 1; # Debug? Set to 0 for no, 1 for yes. + +# ------------------------------------------------------------------------------------------------------------ +# START TIMER: +BEGIN {$t0 = time} + +# ------------------------------------------------------------------------------------------------------------ +# SUBROUTINES: + +# Split the strings of an array, using a de-meta-ed separator: +sub split_strings ($separator, @array) { + return grep {length($_)>0} map {split /\Q$separator\E/, $_} @array; +} + +# ------------------------------------------------------------------------------------------------------------ +# MAIN BODY OF PROGRAM: + +# Inputs: +my @arrays = @ARGV ? eval($ARGV[0]) : +( + # Example 1 Input: + ["one.two.three", "four.five", "six", "."], + # Expected Output: "one","two","three","four","five","six" + + # Example 2 Input: + ["\$perl\$\$", "\$\$raku\$", "\$"], + # Expected Output: "perl","raku" +); + +# Main loop: +for my $aref (@arrays) { + say ''; + my @array = @$aref; + my $separator = splice @array, -1, 1; + say 'Input array = (', join(', ', map {"\"$_\""} @array), ')'; + say 'Separator = ', '"', $separator, '"'; + say 'Output array = (', join(', ', map {"\"$_\""} split_strings($separator, @array)), ')'; +} +exit; + +# ------------------------------------------------------------------------------------------------------------ +# DETERMINE AND PRINT EXECUTION TIME: +END {my $µs = 1000000 * (time - $t0);printf("\nExecution time was %.0fµs.\n", $µs)} +__END__ diff --git a/challenge-253/robbie-hatley/perl/ch-2.pl b/challenge-253/robbie-hatley/perl/ch-2.pl new file mode 100755 index 0000000000..118fa9e22c --- /dev/null +++ b/challenge-253/robbie-hatley/perl/ch-2.pl @@ -0,0 +1,145 @@ +#!/usr/bin/env -S perl -CSDA + +=pod + +-------------------------------------------------------------------------------------------------------------- +COLOPHON: +This is a 110-character-wide Unicode UTF-8 Perl-source-code text file with hard Unix line breaks ("\x0A"). +¡Hablo Español! Говорю Русский. Björt skjöldur. ॐ नमो भगवते वासुदेवाय. 看的星星,知道你是爱。麦藁雪、富士川町、山梨県。 + +-------------------------------------------------------------------------------------------------------------- +TITLE BLOCK: +Solutions in Perl for The Weekly Challenge 253-2. +Written by Robbie Hatley on Mon Jan 22nd, 2023. + +-------------------------------------------------------------------------------------------------------------- +PROBLEM DESCRIPTION: +Task 253-2: Weakest Row +Submitted by: Mohammad S Anwar +You are given an m x n binary matrix i.e. only 0 and 1 where 1 +always appear before 0. A row i is weaker than a row j if one +of the following is true: +a) The number of 1s in row i is less than + the number of 1s in row j. +b) Both rows have the same number of 1 and i < j. +Write a script to return the order of rows from weakest to +strongest. + +Example 1: +Input: $matrix = [ + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 0], + [1, 0, 0, 0, 0], + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 1] + ] +Output: (2, 0, 3, 1, 4) +The number of 1s in each row is: +- Row 0: 2 +- Row 1: 4 +- Row 2: 1 +- Row 3: 2 +- Row 4: 5 + +Example 2: +Input: $matrix = [ + [1, 0, 0, 0], + [1, 1, 1, 1], + [1, 0, 0, 0], + [1, 0, 0, 0] + ] +Output: (0, 2, 3, 1) +The number of 1s in each row is: +- Row 0: 1 +- Row 1: 4 +- Row 2: 1 +- Row 3: 1 + +-------------------------------------------------------------------------------------------------------------- +PROBLEM NOTES: +A combined sort can be indicated by PrimarySort || SecondarySort. In this case, the primary sort is by +"# of 1s" and secondary sort is by index. The "# of 1s" is just sum0(Row), and the indices are just +0..$#$aref. So this subroutine should do the trick: +sub weakest ($aref) { + return sort {sum0(@{$$aref[$a]})<=>sum0(@{$$aref[$b]}) || $a<=>$b} 0..$#$aref; +} + +-------------------------------------------------------------------------------------------------------------- +IO NOTES: +Input is via either built-in variables or via @ARGV. If using @ARGV, provide one argument which must be a +single-quoted array of mxn matrices of 0s and 1s, 1s first, in proper Perl syntax, like so: +./ch-2.pl '([[1,1,1,0],[1,1,0,0]],[[1,0,0],[1,1,1],[1,1,0],[1,1,0]])' + +Output is to STDOUT and will be each input followed by the corresponding output. + +=cut + +# ------------------------------------------------------------------------------------------------------------ +# PRAGMAS AND MODULES USED: + +use v5.38; +use strict; +use warnings; +use utf8; +use warnings FATAL => 'utf8'; +use Sys::Binmode; +use Time::HiRes 'time'; +use List::Util 'sum0'; + +# ------------------------------------------------------------------------------------------------------------ +# GLOBAL VARIABLES: +our $t0 ; # Seconds since 00:00:00 on Thu Jan 1, 1970. +our $db = 1; # Debug? Set to 0 for no, 1 for yes. + +# ------------------------------------------------------------------------------------------------------------ +# START TIMER: +BEGIN {$t0 = time} + +# ------------------------------------------------------------------------------------------------------------ +# SUBROUTINES: + +# Return the row indices of @$aref sorted from "weakest" to "strongest": +sub weakest ($aref) { + return sort {sum0(@{$$aref[$a]})<=>sum0(@{$$aref[$b]}) || $a<=>$b} 0..$#$aref; +} + +# ------------------------------------------------------------------------------------------------------------ +# MAIN BODY OF PROGRAM: + +# Inputs: +my @arrays = @ARGV ? eval($ARGV[0]) : +( + # Example 1 Input: + [ + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 0], + [1, 0, 0, 0, 0], + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 1], + ], + # Expected Output: (2, 0, 3, 1, 4) + + # Example 2 Input: + [ + [1, 0, 0, 0], + [1, 1, 1, 1], + [1, 0, 0, 0], + [1, 0, 0, 0], + ], + # Expected Output: (0, 2, 3, 1) +); + +# Main loop: +for my $aref (@arrays) { + say ''; + say 'Matrix:'; + say join(', ', @$_) for @$aref; + say 'Row indices sorted from weakest to strongest:'; + say '(', join(', ', weakest($aref)), ')'; +} +exit; + +# ------------------------------------------------------------------------------------------------------------ +# DETERMINE AND PRINT EXECUTION TIME: +END {my $µs = 1000000 * (time - $t0);printf("\nExecution time was %.0fµs.\n", $µs)} +__END__ -- cgit From 4dd0b91be05dd4edac8c2447007943c99ccc3786 Mon Sep 17 00:00:00 2001 From: Packy Anderson Date: Tue, 23 Jan 2024 00:19:59 -0500 Subject: Challenge 253 solutions by Packy Anderson * Raku * Perl * Python 1 Blog post --- challenge-253/packy-anderson/README.md | 2 +- challenge-253/packy-anderson/blog.txt | 1 + challenge-253/packy-anderson/perl/ch-1.pl | 23 ++++++++++++ challenge-253/packy-anderson/perl/ch-2.pl | 53 +++++++++++++++++++++++++++ challenge-253/packy-anderson/python/ch-1.py | 24 +++++++++++++ challenge-253/packy-anderson/python/ch-2.py | 56 +++++++++++++++++++++++++++++ challenge-253/packy-anderson/raku/ch-1.raku | 23 ++++++++++++ challenge-253/packy-anderson/raku/ch-2.raku | 51 ++++++++++++++++++++++++++ 8 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 challenge-253/packy-anderson/blog.txt create mode 100755 challenge-253/packy-anderson/perl/ch-1.pl create mode 100755 challenge-253/packy-anderson/perl/ch-2.pl create mode 100755 challenge-253/packy-anderson/python/ch-1.py create mode 100755 challenge-253/packy-anderson/python/ch-2.py create mode 100755 challenge-253/packy-anderson/raku/ch-1.raku create mode 100755 challenge-253/packy-anderson/raku/ch-2.raku diff --git a/challenge-253/packy-anderson/README.md b/challenge-253/packy-anderson/README.md index 336f14bee6..9ec528211e 100644 --- a/challenge-253/packy-anderson/README.md +++ b/challenge-253/packy-anderson/README.md @@ -16,4 +16,4 @@ ## Blog Post -[Sum Enchanted Evening](https://packy.dardan.com/b/GW) +[The Weakest Split](https://packy.dardan.com/b/Gu) diff --git a/challenge-253/packy-anderson/blog.txt b/challenge-253/packy-anderson/blog.txt new file mode 100644 index 0000000000..a428b692cf --- /dev/null +++ b/challenge-253/packy-anderson/blog.txt @@ -0,0 +1 @@ +https://packy.dardan.com/b/Gu \ No newline at end of file diff --git a/challenge-253/packy-anderson/perl/ch-1.pl b/challenge-253/packy-anderson/perl/ch-1.pl new file mode 100755 index 0000000000..4925a259e7 --- /dev/null +++ b/challenge-253/packy-anderson/perl/ch-1.pl @@ -0,0 +1,23 @@ +#!/usr/bin/env perl +use v5.38; + +sub splitOnSeparator($separator, @words) { + my @output; + foreach my $str ( @words ) { + push @output, grep { !/^$/ } split(/\Q$separator/, $str); + } + return @output; +} + +sub solution($separator, @words) { + say 'Input: @words = ("' . join("', '", @words) . '")'; + say ' $separator = "' . $separator . '"'; + my @output = splitOnSeparator($separator, @words); + say 'Output: "' . join('", "', @output) . '"'; +} + +say "Example 1:"; +solution('.', "one.two.three","four.five","six"); + +say "\nExample 2:"; +solution('$', '$perl$$', '$$raku$'); \ No newline at end of file diff --git a/challenge-253/packy-anderson/perl/ch-2.pl b/challenge-253/packy-anderson/perl/ch-2.pl new file mode 100755 index 0000000000..37b7e3db38 --- /dev/null +++ b/challenge-253/packy-anderson/perl/ch-2.pl @@ -0,0 +1,53 @@ +#!/usr/bin/env perl +use v5.38; + +use List::Util qw( sum ); + +sub weakestRows(@matrix) { + my @oneCount = map { sum(@$_) } @matrix; + my @weakest = sort { + # sort by count first + $oneCount[$a] <=> $oneCount[$b] + || + # then by index order + $a cmp $b + } (0 .. $#oneCount); + + return @weakest; +} + +sub formatMatrix($matrix, $indent) { + my @output; + foreach my $row ( @$matrix ) { + my $output_row = q{ } x $indent . " ["; + $output_row .= join(', ', @$row) . "]"; + push @output, $output_row; + } + return "[\n" + . join(",\n", @output) + . "\n" + . q{ } x $indent . "]"; +} + +sub solution(@matrix) { + say 'Input: $matrix = ' . formatMatrix(\@matrix, 17); + my @output = weakestRows(@matrix); + say 'Output: (' . join(', ', @output) . ')'; +} + +say "Example 1:"; +solution( + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 0], + [1, 0, 0, 0, 0], + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 1] + ); + +say "\nExample 2:"; +solution( + [1, 0, 0, 0], + [1, 1, 1, 1], + [1, 0, 0, 0], + [1, 0, 0, 0] + ); \ No newline at end of file diff --git a/challenge-253/packy-anderson/python/ch-1.py b/challenge-253/packy-anderson/python/ch-1.py new file mode 100755 index 0000000000..7d6f592dd7 --- /dev/null +++ b/challenge-253/packy-anderson/python/ch-1.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +def splitOnSeparator(words, separator): + output = [] + for str in words: + output.extend( + list(filter(lambda w: w > "", str.split(separator))) + ) + return output + +def comma_join(arr): + return '"' + '", "'.join(arr) + '"' + +def solution(words, separator): + print(f'Input: @words = ({comma_join(words)})') + print(f' $separator = "{separator}"') + output = splitOnSeparator(words, separator) + print(f'Output: {comma_join(output)}') + +print('Example 1:') +solution(["one.two.three","four.five","six"], '.') + +print('\nExample 2:') +solution(['$perl$$', '$$raku$'], '$') diff --git a/challenge-253/packy-anderson/python/ch-2.py b/challenge-253/packy-anderson/python/ch-2.py new file mode 100755 index 0000000000..50006d5d5e --- /dev/null +++ b/challenge-253/packy-anderson/python/ch-2.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +def weakestRows(matrix): + oneCount = [ sum(row) for row in matrix ] + # sort the rows by their oneCount values + # use the Decorate-Sort-Undecorate idiom + # to convert the dict into a list + # https://docs.python.org/3/howto/sorting.html#decorate-sort-undecorate + decorated = [ + (oneCount[i], i) for i in range(len(oneCount)) + ] + sorted_tuples = sorted( + decorated, + # the - before the first element sorts descending + key=lambda k: (k[0], k[1]) + ) + weakest = [ t[1] for t in sorted_tuples ] + return weakest + +def comma_join(arr): + return ', '.join(map(lambda i: str(i), arr)) + +def formatMatrix(matrix, indent=17): + output = [] + for row in matrix: + output_row = ' ' * indent + ' [' + output_row += ', '.join(map(lambda i: str(i), row)) + output_row += ']' + output.append(output_row) + + return( + "[\n" + ",\n".join(output) + "\n" + + ' ' * indent + ']' + ) + +def solution(matrix): + print(f'Input: $matrix = {formatMatrix(matrix)}') + output = weakestRows(matrix) + print(f'Output: ({comma_join(output)})') + +print('Example 1:') +solution([ + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 0], + [1, 0, 0, 0, 0], + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 1] + ]) + +print('\nExample 2:') +solution([ + [1, 0, 0, 0], + [1, 1, 1, 1], + [1, 0, 0, 0], + [1, 0, 0, 0] + ]) \ No newline at end of file diff --git a/challenge-253/packy-anderson/raku/ch-1.raku b/challenge-253/packy-anderson/raku/ch-1.raku new file mode 100755 index 0000000000..7a365a74dc --- /dev/null +++ b/challenge-253/packy-anderson/raku/ch-1.raku @@ -0,0 +1,23 @@ +#!/usr/bin/env raku +use v6; + +sub splitOnSeparator(@words, $separator) { + my @output; + for @words -> $str { + @output.append( $str.split($separator, :skip-empty) ); + } + return @output; +} + +sub solution(@words, $separator) { + say 'Input: @words = ("' ~ @words.join("', '") ~ '")'; + say ' $separator = "' ~ $separator ~ '"'; + my @output = splitOnSeparator(@words, $separator); + say 'Output: "' ~ @output.join('", "') ~ '"'; +} + +say "Example 1:"; +solution(["one.two.three","four.five","six"], '.'); + +say "\nExample 2:"; +solution(['$perl$$', '$$raku$'], '$'); diff --git a/challenge-253/packy-anderson/raku/ch-2.raku b/challenge-253/packy-anderson/raku/ch-2.raku new file mode 100755 index 0000000000..04f329e880 --- /dev/null +++ b/challenge-253/packy-anderson/raku/ch-2.raku @@ -0,0 +1,51 @@ +#!/usr/bin/env raku +use v6; + +sub weakestRows(@matrix) { + my @oneCount = @matrix.map({ $_.sum }); + my @weakest = (0 .. @oneCount.end).sort: { + # sort by count first + @oneCount[$^a] <=> @oneCount[$^b] + || + # then by index order + $^a <=> $^b + }; + + return @weakest; +} + +sub formatMatrix(@matrix, $indent) { + my @output; + for @matrix -> @row { + my $output_row = q{ } x $indent ~ " ["; + $output_row ~= @row.join(', ') ~ "]"; + @output.push($output_row); + } + return "[\n" + ~ @output.join(",\n") + ~ "\n" + ~ q{ } x $indent ~ "]"; +} + +sub solution(@matrix) { + say 'Input: $matrix = ' ~ formatMatrix(@matrix, 17); + my @output = weakestRows(@matrix); + say 'Output: (' ~ @output.join(', ') ~ ')'; +} + +say "Example 1:"; +solution([ + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 0], + [1, 0, 0, 0, 0], + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 1] + ]); + +say "\nExample 2:"; +solution([ + [1, 0, 0, 0], + [1, 1, 1, 1], + [1, 0, 0, 0], + [1, 0, 0, 0] + ]); -- cgit From 786acd8ebaff190b023730a9d6bc34bc0f83db39 Mon Sep 17 00:00:00 2001 From: Mariano Spadaccini Date: Tue, 23 Jan 2024 10:50:07 +0100 Subject: PWC 253 in Perl --- challenge-253/spadacciniweb/perl/ch-1.pl | 41 +++++++++++++++ challenge-253/spadacciniweb/perl/ch-2.pl | 85 ++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 challenge-253/spadacciniweb/perl/ch-1.pl create mode 100644 challenge-253/spadacciniweb/perl/ch-2.pl diff --git a/challenge-253/spadacciniweb/perl/ch-1.pl b/challenge-253/spadacciniweb/perl/ch-1.pl new file mode 100644 index 0000000000..b6ffebb733 --- /dev/null +++ b/challenge-253/spadacciniweb/perl/ch-1.pl @@ -0,0 +1,41 @@ +#!/usr/bin/env perl + +# Task 1: Split Strings +# Submitted by: Mohammad S Anwar +# +# You are given an array of strings and a character separator. +# Write a script to return all words separated by the given character excluding empty string. +# +# Example 1 +# Input: @words = ("one.two.three","four.five","six") +# $separator = "." +# Output: "one","two","three","four","five","six" +# +# Example 2 +# Input: @words = ("$perl$$", "$$raku$") +# $separator = "$" +# Output: "perl","raku" + + +use strict; +use warnings; + +my @words = ("one.two.three","four.five","six"); +my $separator = "."; +split_strings(\@words, $separator); + +@words = ('$perl$$', '$$raku$'); +$separator = '$'; +split_strings(\@words, $separator); + +exit 0; + +sub split_strings { + my $words = shift; + my $separator = shift; + + printf "Output: \"%s\"\n", join '","', map { join '","', grep {!/^$/} split /\Q$separator\E/, $_ } + @$words; + + return 0; +} diff --git a/challenge-253/spadacciniweb/perl/ch-2.pl b/challenge-253/spadacciniweb/perl/ch-2.pl new file mode 100644 index 0000000000..e9de1b2539 --- /dev/null +++ b/challenge-253/spadacciniweb/perl/ch-2.pl @@ -0,0 +1,85 @@ +#!/usr/bin/env perl + +# Task 2: Weakest Row +# Submitted by: Mohammad S Anwar +# +# You are given an m x n binary matrix i.e. only 0 and 1 where 1 always appear before 0. +# A row i is weaker than a row j if one of the following is true: +# +# a) The number of 1s in row i is less than the number of 1s in row j. +# b) Both rows have the same number of 1 and i < j. +# +# Write a script to return the order of rows from weakest to strongest. +# Example 1 +# +# Input: $matrix = [ +# [1, 1, 0, 0, 0], +# [1, 1, 1, 1, 0], +# [1, 0, 0, 0, 0], +# [1, 1, 0, 0, 0], +# [1, 1, 1, 1, 1] +# ] +# Output: (2, 0, 3, 1, 4) +# +# The number of 1s in each row is: +# - Row 0: 2 +# - Row 1: 4 +# - Row 2: 1 +# - Row 3: 2 +# - Row 4: 5 +# +# Example 2 +# Input: $matrix = [ +# [1, 0, 0, 0], +# [1, 1, 1, 1], +# [1, 0, 0, 0], +# [1, 0, 0, 0] +# ] +# Output: (0, 2, 3, 1) +# +# The number of 1s in each row is: +# - Row 0: 1 +# - Row 1: 4 +# - Row 2: 1 +# - Row 3: 1 + +use strict; +use warnings; +use List::Util qw/sum/; + + +my $matrix = [ + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 0], + [1, 0, 0, 0, 0], + [1, 1, 0, 0, 0], + [1, 1, 1, 1, 1] + ]; +order_rows($matrix); + +$matrix = [ + [1, 0, 0, 0], + [1, 1, 1, 1], + [1, 0, 0, 0], + [1, 0, 0, 0] + ]; +order_rows($matrix); + +exit 0; + +sub order_rows { + my $matrix = shift; + + my %sum_rows; + foreach my $i (0..(scalar(@$matrix) -1)) { + $sum_rows{$i} = sum(@{ $matrix->[$i] }); + } + + printf "Output: (%s)\n", join ', ' , map { $_ } + sort { $sum_rows{$a} <=> $sum_rows{$b} + || + $a <=> $b + } keys %sum_rows; + + return 0; +} -- cgit From 54d8f1ea69225d4dce82a81161753f9177a02083 Mon Sep 17 00:00:00 2001 From: Roger Bell_West Date: Tue, 23 Jan 2024 11:31:15 +0000 Subject: RogerBW solutions for challenge no. 253 --- challenge-253/roger-bell-west/javascript/ch-1.js | 52 ++++++ challenge-253/roger-bell-west/javascript/ch-2.js | 52 ++++++ challenge-253/roger-bell-west/kotlin/ch-1.kt | 24 +++ challenge-253/roger-bell-west/kotlin/ch-2.kt | 23 +++ challenge-253/roger-bell-west/lua/ch-1.lua | 69 ++++++++ challenge-253/roger-bell-west/lua/ch-2.lua | 60 +++++++ challenge-253/roger-bell-west/perl/ch-1.pl | 19 +++ challenge-253/roger-bell-west/perl/ch-2.pl | 19 +++ challenge-253/roger-bell-west/postscript/ch-1.ps | 138 ++++++++++++++++ challenge-253/roger-bell-west/postscript/ch-2.ps | 193 +++++++++++++++++++++++ challenge-253/roger-bell-west/python/ch-1.py | 21 +++ challenge-253/roger-bell-west/python/ch-2.py | 19 +++ challenge-253/roger-bell-west/raku/ch-1.p6 | 18 +++ challenge-253/roger-bell-west/raku/ch-2.p6 | 15 ++ challenge-253/roger-bell-west/ruby/ch-1.rb | 23 +++ challenge-253/roger-bell-west/ruby/ch-2.rb | 22 +++ challenge-253/roger-bell-west/rust/ch-1.rs | 31 ++++ challenge-253/roger-bell-west/rust/ch-2.rs | 36 +++++ challenge-253/roger-bell-west/scala/ch-1.scala | 26 +++ challenge-253/roger-bell-west/scala/ch-2.scala | 25 +++ challenge-253/roger-bell-west/tests.yaml | 81 ++++++++++ 21 files changed, 966 insertions(+) create mode 100755 challenge-253/roger-bell-west/javascript/ch-1.js create mode 100755 challenge-253/roger-bell-west/javascript/ch-2.js create mode 100644 challenge-253/roger-bell-west/kotlin/ch-1.kt create mode 100644 challenge-253/roger-bell-west/kotlin/ch-2.kt create mode 100755 challenge-253/roger-bell-west/lua/ch-1.lua create mode 100755 challenge-253/roger-bell-west/lua/ch-2.lua create mode 100755 challenge-253/roger-bell-west/perl/ch-1.pl create mode 100755 challenge-253/roger-bell-west/perl/ch-2.pl create mode 100644 challenge-253/roger-bell-west/postscript/ch-1.ps create mode 100644 challenge-253/roger-bell-west/postscript/ch-2.ps create mode 100755 challenge-253/roger-bell-west/python/ch-1.py create mode 100755 challenge-253/roger-bell-west/python/ch-2.py create mode 100755 challenge-253/roger-bell-west/raku/ch-1.p6 create mode 100755 challenge-253/roger-bell-west/raku/ch-2.p6 create mode 100755 challenge-253/roger-bell-west/ruby/ch-1.rb create mode 100755 challenge-253/roger-bell-west/ruby/ch-2.rb create mode 100755 challenge-253/roger-bell-west/rust/ch-1.rs create mode 100755 challenge-253/roger-bell-west/rust/ch-2.rs create mode 100644 challenge-253/roger-bell-west/scala/ch-1.scala create mode 100644 challenge-253/roger-bell-west/scala/ch-2.scala create mode 100644 challenge-253/roger-bell-west/tests.yaml diff --git a/challenge-253/roger-bell-west/javascript/ch-1.js b/challenge-253/roger-bell-west/javascript/ch-1.js new file mode 100755 index 0000000000..eec930e572 --- /dev/null +++ b/challenge-253/roger-bell-west/javascript/ch-1.js @@ -0,0 +1,52 @@ +#! /usr/bin/node + +"use strict" + +// by Frank Tan +// https://stackoverflow.com/questions/38400594/javascript-deep-comparison +function deepEqual(a,b) +{ + if( (typeof a == 'object' && a != null) && + (typeof b == 'object' && b != null) ) + { + var count = [0,0]; + for( var key in a) count[0]++; + for( var key in b) count[1]++; + if( count[0]-count[1] != 0) {return false;} + for( var key in a) + { + if(!(key in b) || !deepEqual(a[key],b[key])) {return false;} + } + for( var key in b) + { + if(!(key in a) || !deepEqual(b[key],a[key])) {return false;} + } + return true; + } + else + { + return a === b; + } +} + +function splitstrings(a, sep) { + let p = []; + for (let s of a) { + let r = s.split(sep).filter(n => n.length > 0); + p = p.concat(r) + } + return p; +} + +if (deepEqual(splitstrings(['one.two.three', 'four.five', 'six'], '.'), ['one', 'two', 'three', 'four', 'five', 'six'])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (deepEqual(splitstrings(['$perl$$', '$$raku$'], '$'), ['perl', 'raku'])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write("\n"); diff --git a/challenge-253/roger-bell-west/javascript/ch-2.js b/challenge-253/roger-bell-west/javascript/ch-2.js new file mode 100755 index 0000000000..dc526d0b86 --- /dev/null +++ b/challenge-253/roger-bell-west/javascript/ch-2.js @@ -0,0 +1,52 @@ +#! /usr/bin/node + +"use strict" + +// by Frank Tan +// https://stackoverflow.com/questions/38400594/javascript-deep-comparison +function deepEqual(a,b) +{ + if( (typeof a == 'object' && a != null) && + (typeof b == 'object' && b != null) ) + { + var count = [0,0]; + for( var key in a) count[0]++; + for( var key in b) count[1]++; + if( count[0]-count[1] != 0) {return false;} + for( var key in a) + { + if(!(key in b) || !deepEqual(a[key],b[key])) {return false;} + } + for( var key in b) + { + if(!(key in a) || !deepEqual(b[key],a[key])) {return false;} + } + return true; + } + else + { + return a === b; + } +} + +function weakestrows(a) { + let p = Array(a.length).fill().map((element, index) => index); + let b = a.map(n => n.reduce((x,y) => x+y)); + p.sort(function(l, r) { + return b[l] - b[r]; + }); + return p; +} + +if (deepEqual(weakestrows([[1, 1, 0, 0, 0], [1, 1, 1, 1, 0], [1, 0, 0, 0, 0], [1, 1, 0, 0, 0], [1, 1, 1, 1, 1]]), [2, 0, 3, 1, 4])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (deepEqual(weakestrows([[1, 0, 0, 0], [1, 1, 1, 1], [1, 0, 0, 0], [1, 0, 0, 0]]), [0, 2, 3, 1])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write("\n"); diff --git a/challenge-253/roger-bell-west/kotlin/ch-1.kt b/challenge-253/roger-bell-west/kotlin/ch-1.kt new file mode 100644 index 0000000000..3918a407bb --- /dev/null +++ b/challenge-253/roger-bell-west/kotlin/ch-1.kt @@ -0,0 +1,24 @@ +fun splitstrings(a: List, sep: String): List { + var p = ArrayList() + for (s in a) { + p.addAll(s.split(sep).filter{it.length > 0}) + } + return p.toList() +} + +fun main() { + + if (splitstrings(listOf("one.two.three", "four.five", "six"), ".") == listOf("one", "two", "three", "four", "five", "six")) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (splitstrings(listOf("\$perl\$\$", "\$\$raku\$"), "\$") == listOf("perl", "raku")) { + print("Pass") + } else { + print("Fail") + } + println("") + +} diff --git a/challenge-253/roger-bell-west/kotlin/ch-2.kt b/challenge-253/roger-bell-west/kotlin/ch-2.kt new file mode 100644 index 0000000000..4a0b428e71 --- /dev/null +++ b/challenge-253/roger-bell-west/kotlin/ch-2.kt @@ -0,0 +1,23 @@ +fun weakestrows(a: List>): List { + var p = ArrayList(generateSequence(0) { it + 1 }.take(a.size).toList()) + val b = a.map{it.sum()} + p.sortBy {b[it]} + return p.toList() +} + +fun main() { + + if (weakestrows(listOf(listOf(1, 1, 0, 0, 0), listOf(1, 1, 1, 1, 0), listOf(1, 0, 0, 0, 0), listOf(1, 1, 0, 0, 0), listOf(1, 1, 1, 1, 1))) == listOf(2, 0, 3, 1, 4)) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (weakestrows(listOf(listOf(1, 0, 0, 0), listOf(1, 1, 1, 1), listOf(1, 0, 0, 0), listOf(1, 0, 0, 0))) == listOf(0, 2, 3, 1)) { + print("Pass") + } else { + print("Fail") + } + println("") + +} diff --git a/challenge-253/roger-bell-west/lua/ch-1.lua b/challenge-253/roger-bell-west/lua/ch-1.lua new file mode 100755 index 0000000000..bef4c6baf3 --- /dev/null +++ b/challenge-253/roger-bell-west/lua/ch-1.lua @@ -0,0 +1,69 @@ +#! /usr/bin/lua + +-- by Michael Anderson at +-- https://stackoverflow.com/questions/8722620/comparing-two-index-tables-by-index-value-in-lua +-- modified by Roger +function recursive_compare(t1,t2) + -- Use usual comparison first. + if t1==t2 then return true end + -- We only support non-default behavior for tables + if (type(t1)~="table") then return false end + -- They better have the same metatables + local mt1 = getmetatable(t1) + local mt2 = getmetatable(t2) + if( not recursive_compare(mt1,mt2) ) then return false end + -- Build list of all keys + local kk = {} + for k1, _ in pairs(t1) do + kk[k1] = true + end + for k2, _ in pairs(t2) do + kk[k2] = true + end + -- Check each key that exists in at least one table + for _, k in ipairs(kk) do + if (not recursive_compare(t1[k], t2[k])) then + return false + end + end + return true +end + +-- bart at https://stackoverflow.com/questions/1426954/split-string-in-lua +function split(inputstr, sep) + sep=sep or '%s' + local t={} + for field,s in string.gmatch(inputstr, "([^"..sep.."]*)("..sep.."?)") do + table.insert(t,field) + if s=="" then + return t + end + end +end + +function splitstrings(a, sep) + local p = {} + for _i, s in ipairs(a) do + for _j, n in ipairs(split(s), sep) do + if #n > 0 then + table.insert(p, n) + end + end + end + return p +end + +if recursive_compare(splitstrings({"one.two.three", "four.five", "six"}, "."), {"one", "two", "three", "four", "five", "six"}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if recursive_compare(splitstrings({"$perl$$", "$$raku$"}, "$"), {"perl", "raku"}) then + io.write("Pass") +else + io.write("FAIL") +end +print("") + diff --git a/challenge-253/roger-bell-west/lua/ch-2.lua b/challenge-253/roger-bell-west/lua/ch-2.lua new file mode 100755 index 0000000000..bc79e3a4b0 --- /dev/null +++ b/challenge-253/roger-bell-west/lua/ch-2.lua @@ -0,0 +1,60 @@ +#! /usr/bin/lua + +-- by Michael Anderson at +-- https://stackoverflow.com/questions/8722620/comparing-two-index-tables-by-index-value-in-lua +-- modified by Roger +function recursive_compare(t1,t2) + -- Use usual comparison first. + if t1==t2 then return true end + -- We only support non-default behavior for tables + if (type(t1)~="table") then return false end + -- They better have the same metatables + local mt1 = getmetatable(t1) + local mt2 = getmetatable(t2) + if( not recursive_compare(mt1,mt2) ) then return false end + -- Build list of all keys + local kk = {} + for k1, _ in pairs(t1) do + kk[k1] = true + end + for k2, _ in pairs(t2) do + kk[k2] = true + end + -- Check each key that exists in at least one table + for _, k in ipairs(kk) do + if (not recursive_compare(t1[k], t2[k])) then + return false + end + end + return true +end + +function weakestrows(a) + local p = {} + local b = {} + for i, n in ipairs(a) do + p[i] = i - 1 + local sum = 0 + for _j, m in ipairs(n) do + sum = sum + m + end + table.insert(b, sum) + end + table.sort(p, function(i, j) return b[i + 1] < b[j + 1] end) + return p +end + +if recursive_compare(weakestrows({{1, 1, 0, 0, 0}, {1, 1, 1, 1, 0}, {1, 0, 0, 0, 0}, {1, 1, 0, 0, 0}, {1, 1, 1, 1, 1}}), {2, 0, 3, 1, 4}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if recursive_compare(weakestrows({{1, 0, 0, 0}, {1, 1, 1, 1}, {1, 0, 0, 0}, {1, 0, 0, 0}}), {0, 2, 3, 1}) then + io.write("Pass") +else + io.write("FAIL") +end +print("") + diff --git a/challenge-253/roger-bell-west/perl/ch-1.pl b/challenge-253/roger-bell-west/perl/ch-1.pl new file mode 100755 index 0000000000..714727e35a --- /dev/null +++ b/challenge-253/roger-bell-west/perl/ch-1.pl @@ -0,0 +1,19 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 2; + +is_deeply(splitstrings(['one.two.three', 'four.five', 'six'], '.'), ['one', 'two', 'three', 'four', 'five', 'six'], 'example 1'); +is_deeply(splitstrings(['$perl$$', '$$raku$'], '$'), ['perl', 'raku'], 'example 2'); + +sub splitstrings($a, $ssep) { + my @p; + (my $sep = $ssep) =~ s/([^A-Z0-9])/\\$1/gi; + foreach my $s (@{$a}) { + push @p, grep /./, split($sep, $s); + } + return \@p; +} diff --git a/challenge-253/roger-bell-west/perl/ch-2.pl b/challenge-253/roger-bell-west/perl/ch-2.pl new file mode 100755 index 0000000000..f853ab3517 --- /dev/null +++ b/challenge-253/roger-bell-west/perl/ch-2.pl @@ -0,0 +1,19 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 2; + +is_deeply(weakestrows([[1, 1, 0, 0, 0], [1, 1, 1, 1, 0], [1, 0, 0, 0, 0], [1, 1, 0, 0, 0], [1, 1, 1, 1, 1]]), [2, 0, 3, 1, 4], 'example 1'); +is_deeply(weakestrows([[1, 0, 0, 0], [1, 1, 1, 1], [1, 0, 0, 0], [1, 0, 0, 0]]), [0, 2, 3, 1], 'example 2'); + +use List::Util qw(sum); + +sub weakestrows($aa) { + my @p = (0 .. $#{$aa}); + my @bb = map {sum(@{$_})} @{$aa}; + @p = sort {$bb[$a] <=> $bb[$b]} @p; + return \@p; +} diff --git a/challenge-253/roger-bell-west/postscript/ch-1.ps b/challenge-253/roger-bell-west/postscript/ch-1.ps new file mode 100644 index 0000000000..067989d10d --- /dev/null +++ b/challenge-253/roger-bell-west/postscript/ch-1.ps @@ -0,0 +1,138 @@ +%!PS + +% begin included library code +% see https://codeberg.org/Firedrake/postscript-libraries/ +/deepeq { + 2 dict begin + /a exch def + /b exch def + a type b type eq { + a type /dicttype eq { + a length b length eq { + << + a { + pop + true + } forall + b { + pop + true + } forall + >> + true exch + { + pop + dup a exch known { + dup b exch known { + dup a exch get exch b exch get deepeq not { + pop false + } if + } { + false + } ifelse + } { + false + } ifelse + } forall + } { + false + } ifelse + } { + a type dup /arraytype eq exch /stringtype eq or { + a length b length eq { + true + 0 1 a length 1 sub { + dup a exch get exch b exch get deepeq not { + pop false + exit + } if + } for + } { + false + } ifelse + } { + a b eq + } ifelse + } ifelse + } { + false + } ifelse + end +} bind def + +/test.start { + print (:) print + /test.pass 0 def + /test.count 0 def +} bind def + +/test.end { + ( ) print + test.count 0 gt { + (Passed ) print + test.pass (...) cvs print + (/) print + test.count (...) cvs print + ( \() print + test.pass 100 mul test.count idiv (...) cvs print + (%\)) print + (\r\n) print + } if +} bind def + +/strsplit % (ajbjc) (j) -> [ (a) (b) (c) ] +{ + 1 dict begin + /sep exch def + [ exch + { + dup length 0 eq { + pop + exit + } { + sep search { + exch pop + dup length 0 eq { + pop + } { + exch + } ifelse + } { + () + } ifelse + } ifelse + } loop + ] + end +} bind def + +/test { + /test.count test.count 1 add def + { + /test.pass test.pass 1 add def + } { + ( ) print + test.count (....) cvs print + (-fail) print + } ifelse +} bind def + + +% end included library code + +/splitstrings { + 0 dict begin + /sep exch def + [ exch + { + sep strsplit + aload pop + } forall + ] + end +} bind def + +(splitstrings) test.start +[(one.two.three) (four.five) (six)] (.) splitstrings [(one) (two) (three) (four) (five) (six)] deepeq test +[($perl$$) ($$raku$)] ($) splitstrings [(perl) (raku)] deepeq test +test.end diff --git a/challenge-253/roger-bell-west/postscript/ch-2.ps b/challenge-253/roger-bell-west/postscript/ch-2.ps new file mode 100644 index 0000000000..c013e8511a --- /dev/null +++ b/challenge-253/roger-bell-west/postscript/ch-2.ps @@ -0,0 +1,193 @@ +%!PS + +% begin included library code +% see https://codeberg.org/Firedrake/postscript-libraries/ +/test.start { + print (:) print + /test.pass 0 def + /test.count 0 def +} bind def + +/map { % array proc -> array + 2 dict begin + /p exch def + [ exch + { + p + } forall + ] + end +} bind def + +/reduce { % array proc -> value + 2 dict begin + /p exch def + /a exch def + a 0 get + 1 1 a length 1 sub { + a exch get + p + } for + end +} bind def + +/quicksort.cmp { + 2 copy + lt { + pop pop -1 + } { + gt { + 1 + } { + 0 + } ifelse + } ifelse +} bind def + +/mergesort.merge { + 4 dict begin + /right exch def + /left exch def + /li 0 def + /ri 0 def + [ + { + li left length ge ri right length ge or { + exit + } if + left li get right ri get cmp 0 le { + left li get + /li li 1 add def + } { + right ri get + /ri ri 1 add def + } ifelse + } loop + li left length lt { + left li left length li sub getinterval aload pop + } if + ri right length lt { + right ri right length ri sub getinterval aload pop + } if + ] + end +} bind def + +/test.end { + ( ) print + test.count 0 gt { + (Passed ) print + test.pass (...) cvs print + (/) print + test.count (...) cvs print + ( \() print + test.pass 100 mul test.count idiv (...) cvs print + (%\)) print + (\r\n) print + } if +} bind def + +/deepeq { + 2 dict begin + /a exch def + /b exch def + a type b type eq { + a type /dicttype eq { + a length b length eq { + << + a { + pop + true + } forall + b { + pop + true + } forall + >> + true exch + { + pop + dup a exch known { + dup b exch known { + dup a exch get exch b exch get deepeq not { + pop false + } if + } { + false + } ifelse + } { + false + } ifelse + } forall + } { + false + } ifelse + } { + a type dup /arraytype eq exch /stringtype eq or { + a length b length eq { + true + 0 1 a length 1 sub { + dup a exch get exch b exch get deepeq not { + pop false + exit + } if + } for + } { + false + } ifelse + } { + a b eq + } ifelse + } ifelse + } { + false + } ifelse + end +} bind def + +/mergesort.with_comparator { % [ a c b ] { comparator } -> [ a b c ] + 5 dict begin + /cmp where { + pop + } { + /cmp exch def + } ifelse + /m exch def + m length 1 le { + m + } { + /l2 m length 2 idiv def + /left m 0 l2 getinterval mergesort.with_comparator def + /right m l2 m length l2 sub getinterval mergesort.with_comparator def + left right mergesort.merge + } ifelse + end +} bind def + +/test { + /test.count test.count 1 add def + { + /test.pass test.pass 1 add def + } { + ( ) print + test.count (....) cvs print + (-fail) print + } ifelse +} bind def + + +% end included library code + +/weakestrows { + 0 dict begin + /a exch def + /p [ 0 1 a length 1 sub {} for ] def + /b a { { add } reduce } map def + p { b exch get exch b exch get exch quicksort.cmp } mergesort.with_comparator + end +} bind def + +(weakestrows) test.start +[[1 1 0 0 0] [1 1 1 1 0] [1 0 0 0 0] [1 1 0 0 0] [1 1 1 1 1]] weakestrows [2 0 3 1 4] deepeq test +[[1 0 0 0] [1 1 1 1] [1 0 0 0] [1 0 0 0]] weakestrows [0 2 3 1] deepeq test +test.end diff --git a/challenge-253/roger-bell-west/python/ch-1.py b/challenge-253/roger-bell-west/python/ch-1.py new file mode 100755 index 0000000000..af4f110b05 --- /dev/null +++ b/challenge-253/roger-bell-west/python/ch-1.py @@ -0,0 +1,21 @@ +#! /usr/bin/python3 + +def splitstrings(a, sep): + p = [] + for s in a: + for n in s.split(sep): + if len(n) > 0: + p.append(n) + return p + +import unittest + +class TestSplitstrings(unittest.TestCase): + + def test_ex1(self): + self.assertEqual(splitstrings(["one.two.three", "four.five", "six"], "."), ["one", "two", "three", "four", "five", "six"], 'example 1') + + def test_ex2(self): + self.assertEqual(splitstrings(["$perl$$", "$$raku$"], "$"), ["perl", "raku"], 'example 2') + +unittest.main() diff --git a/challenge-253/roger-bell-west/python/ch-2.py b/challenge-253/roger-bell-west/python/ch-2.py new file mode 100755 index 0000000000..80fa491683 --- /dev/null +++ b/challenge-253/roger-bell-west/python/ch-2.py @@ -0,0 +1,19 @@ +#! /usr/bin/python3 + +def weakestrows(a): + p = list(range(len(a))) + b = [sum(n) for n in a] + p.sort(key = lambda i: b[i]) + return p + +import unittest + +class TestWeakestrows(unittest.TestCase): + + def test_ex1(self): + self.assertEqual(weakestrows([[1, 1, 0, 0, 0], [1, 1, 1, 1, 0], [1, 0, 0, 0, 0], [1, 1, 0, 0, 0], [1, 1, 1, 1, 1]]), [2, 0, 3, 1, 4], 'example 1') + + def test_ex2(self): + self.assertEqual(weakestrows([[1, 0, 0, 0], [1, 1, 1, 1], [1, 0, 0, 0], [1, 0, 0, 0]]), [0, 2, 3, 1], 'example 2') + +unittest.main() diff --git a/challenge-253/roger-bell-west/raku/ch-1.p6 b/challenge-253/roger-bell-west/raku/ch-1.p6 new file mode 100755 index 0000000000..72d235811e --- /dev/null +++ b/challenge-253/roger-bell-west/raku/ch-1.p6 @@ -0,0 +1,18 @@ +#! /usr/bin/raku + +use Test; + +plan 2; + +is-deeply(splitstrings(['one.two.three', 'four.five', 'six'], '.'), ['one', 'two', 'three', 'four', 'five', 'six'], 'example 1'); +is-deeply(splitstrings(['$perl$$', '$$raku$'], '$'), ['perl', 'raku'], 'example 2'); + +sub splitstrings(@a, $ssep) { + my @p; + my $sep = $ssep; + $sep ~~ s:g/(<[^A..Z0..9]>)/\\$1/; + for @a -> $s { + @p.append($s.split($sep).grep(/./)); + } + return @p; +} diff --git a/challenge-253/roger-bell-west/raku/ch-2.p6 b/challenge-253/roger-bell-west/raku/ch-2.p6 new file mode 100755 index 0000000000..0d3989e624 --- /dev/null +++ b/challenge-253/roger-bell-west/raku/ch-2.p6 @@ -0,0 +1,15 @@ +#! /usr/bin/raku + +use Test; + +plan 2; + +is-deeply(weakestrows([[1, 1, 0, 0, 0], [1, 1, 1, 1, 0], [1, 0, 0, 0, 0], [1, 1, 0, 0, 0], [1, 1, 1, 1, 1]]), [2, 0, 3, 1, 4], 'example 1'); +is-deeply(weakestrows([[1, 0, 0, 0], [1, 1, 1, 1], [1, 0, 0, 0], [1, 0, 0, 0]]), [0, 2, 3, 1], 'example 2'); + +sub weakestrows(@aa) { + my @p = (0 .. @aa.end); + my @bb = @aa.map({$_.sum}); + @p = @p.sort({@bb[$^a] <=> @bb[$^b]}); + return @p; +} diff --git a/challenge-253/roger-bell-west/ruby/ch-1.rb b/challenge-253/roger-bell-west/ruby/ch-1.rb new file mode 100755 index 0000000000..6f77b10013 --- /dev/null +++ b/challenge-253/roger-bell-west/ruby/ch-1.rb @@ -0,0 +1,23 @@ +#! /usr/bin/ruby + +def splitstrings(a, sep) + p = [] + a.each do |s| + p += s.split(sep).find_all {|n| n.length > 0} + end + return p +end + +require 'test/unit' + +class TestSplitstrings < Test::Unit::TestCase + + def test_ex1 + assert_equal(['one', 'two', 'three', 'four', 'five', 'six'], splitstrings(['one.two.three', 'four.five', 'six'], '.')) + end + + def test_ex2 + assert_equal(['perl', 'raku'], splitstrings(['$perl$$', '$$raku$'], '$')) + end + +end diff --git a/challenge-253/roger-bell-west/ruby/ch-2.rb b/challenge-253/roger-bell-west/ruby/ch-2.rb new file mode 100755 index 0000000000..93fb225bda --- /dev/null +++ b/challenge-253/roger-bell-west/ruby/ch-2.rb @@ -0,0 +1,22 @@ +#! /usr/bin/ruby + +def weakestrows(a) + p = (0...a.length()) + b = a.map { |n| n.sum } + p = p.sort_by { |x| b[x] } + return p +end + +require 'test/unit' + +class TestWeakestrows < Test::Unit::TestCase + + def test_ex1 + assert_equal([2, 0, 3, 1, 4], weakestrows([[1, 1, 0, 0, 0], [1, 1, 1, 1, 0], [1, 0, 0, 0, 0], [1, 1, 0, 0, 0], [1, 1, 1, 1, 1]])) + end + + def test_ex2 + assert_equal([0, 2, 3, 1], weakestrows([[1, 0, 0, 0], [1, 1, 1, 1], [1, 0, 0, 0], [1, 0, 0, 0]])) + end + +end diff --git a/challenge-253/roger-bell-west/rust/ch-1.rs b/challenge-253/roger-bell-west/rust/ch-1.rs new file mode 100755 index 0000000000..eb0e724a7e --- /dev/null +++ b/challenge-253/roger-bell-west/rust/ch-1.rs @@ -0,0 +1,31 @@ +#! /bin/sh +//usr/bin/env rustc --test $0 -o ${0}x && ./${0}x --nocapture; rm -f ${0}x ; exit + +#[test] +fn test_ex1() { + assert_eq!( + splitstrings(vec!["one.two.three", "four.five", "six"], "."), + vec!["one", "two", "three", "four", "five", "six"] + ); +} + +#[test] +fn test_ex2() { + assert_eq!( + splitstrings(vec!["$perl$$", "$$raku$"], "$"), + vec!["perl", "raku"] + ); +} + +fn splitstrings(a: Vec<&str>, sep: &str) -> Vec { + let mut p = Vec::new(); + for s in a { + let mut r = s + .split(sep) + .filter(|n| n.len() > 0) + .map(|n| n.to_string()) + .collect::>(); + p.append(&mut r); + } + p +} diff --git a/challenge-253/roger-bell-west/rust/ch-2.rs b/challenge-253/roger-bell-west/rust/ch-2.rs new file mode 100755 index 0000000000..8a3b806db6 --- /dev/null +++ b/challenge-253/roger-bell-west/rust/ch-2.rs @@ -0,0 +1,36 @@ +#! /bin/sh +//usr/bin/env rustc --test $0 -o ${0}x && ./${0}x --nocapture; rm -f ${0}x ; exit + +#[test] +fn test_ex1() { + assert_eq!( + weakestrows(vec![ + vec![1, 1, 0, 0, 0], + vec![1, 1, 1, 1, 0], + vec![1, 0, 0, 0, 0], + vec![1, 1, 0, 0, 0], + vec![1, 1, 1, 1, 1] + ]), + vec![2, 0, 3, 1, 4] + ); +} + +#[test] +fn test_ex2() { + assert_eq!( + weakestrows(vec![ + vec![1, 0, 0, 0], + vec![1, 1, 1, 1], + vec![1, 0, 0, 0], + vec![1, 0, 0, 0] + ]), + vec![0, 2, 3, 1] + ); +} + +fn weakestrows(a: Vec>) -> Vec { + let mut p = (0..a.len()).collect::>(); + let b: Vec = a.iter().map(|n| n.iter().sum()).collect(); + p.sort_by(|l, r| b[*l].cmp(&b[*r])); + p +} diff --git a/challenge-253/roger-bell-west/scala/ch-1.scala b/challenge-253/roger-bell-west/scala/ch-1.scala new file mode 100644 index 0000000000..9bc91f9eda --- /dev/null +++ b/challenge-253/roger-bell-west/scala/ch-1.scala @@ -0,0 +1,26 @@ +import scala.collection.mutable.ListBuffer + +object Splitstrings { + def splitstrings(a: List[String], sep: String): List[String] = { + var p = new ListBuffer[String] + for (s <- a) { + p.append(s.split("[" + sep + "]").filter(n => n.length > 0): _*) + } + return p.toList + } + def main(args: Array[String]) { + if (splitstrings(List("one.two.three", "four.five", "six"), ".") == List("one", "two", "three", "four", "five", "six")) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (splitstrings(List("$perl$$", "$$raku$"), "$") == List("perl", "raku")) { + print("Pass") + } else { + print("Fail") + } + println("") + + } +} diff --git a/challenge-253/roger-bell-west/scala/ch-2.scala b/challenge-253/roger-bell-west/scala/ch-2.scala new file mode 100644 index 0000000000..9c5034fd89 --- /dev/null +++ b/challenge-253/roger-bell-west/scala/ch-2.scala @@ -0,0 +1,25 @@ +import scala.collection.mutable.ListBuffer + +object Weakestrows { + def weakestrows(a: List[List[Int]]): List[Int] = { + var p = List.range(0, a.size).to[ListBuffer] + val b = a.map(n => n.sum) + p = p.sortWith(b(_) < b(_)) + return p.toList + } + def main(args: Array[String]) { + if (weakestrows(List(List(1, 1, 0, 0, 0), List(1, 1, 1, 1, 0), List(1, 0, 0, 0, 0), List(1, 1, 0, 0, 0), List(1, 1, 1, 1, 1))) == List(2, 0, 3, 1, 4)) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (weakestrows(List(List(1, 0, 0, 0), List(1, 1, 1, 1), List(1, 0, 0, 0), List(1, 0, 0, 0))) == List(0, 2, 3, 1)) { + print("Pass") + } else { + print("Fail") + } + println("") + + } +} diff --git a/challenge-253/roger-bell-west/tests.yaml b/challenge-253/roger-bell-west/tests.yaml new file mode 100644 index 0000000000..a6555a3c82 --- /dev/null +++ b/challenge-253/roger-bell-west/tests.yaml @@ -0,0 +1,81 @@ +--- +ch-1: + - function: splitstrings + multiarg: true + arguments: + - - one.two.three + - four.five + - six + - . + result: + - one + - two + - three + - four + - five + - six + - multiarg: true + arguments: + - - '$perl$$' + - '$$raku$' + - '$' + result: + - perl + - raku +ch-2: + - function: weakestrows + arguments: + - - 1 + - 1 + - 0 + - 0 + - 0 + - - 1 + - 1 + - 1 + - 1 + - 0 + - - 1 + - 0 + - 0 + - 0 + - 0 + - - 1 + - 1 + - 0 + - 0 + - 0 + - - 1 + - 1 + - 1 + - 1 + - 1 + result: + - 2 + - 0 + - 3 + - 1 + - 4 + - function: weakestrows + arguments: + - - 1 + - 0 + - 0 + - 0 + - - 1 + - 1 + - 1 + - 1 + - - 1 + - 0 + - 0