aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2023-12-31 12:42:57 +0000
committerGitHub <noreply@github.com>2023-12-31 12:42:57 +0000
commitd0ca0f781d260073d5960d0a01b1be43cafa4bd2 (patch)
tree873e95c30cf310afc07cb04d1b392a74772382da
parent4dd3e432cc5d1869153aa6daf30cf5ea035fbdbd (diff)
parenta56e4b8fbdd823d7cd9939c9b42865fea6642643 (diff)
downloadperlweeklychallenge-club-d0ca0f781d260073d5960d0a01b1be43cafa4bd2.tar.gz
perlweeklychallenge-club-d0ca0f781d260073d5960d0a01b1be43cafa4bd2.tar.bz2
perlweeklychallenge-club-d0ca0f781d260073d5960d0a01b1be43cafa4bd2.zip
Merge pull request #9315 from jo-37/contrib
Solutions to challenge 249
-rwxr-xr-xchallenge-249/jo-37/perl/ch-1.pl62
-rwxr-xr-xchallenge-249/jo-37/perl/ch-2.pl83
2 files changed, 145 insertions, 0 deletions
diff --git a/challenge-249/jo-37/perl/ch-1.pl b/challenge-249/jo-37/perl/ch-1.pl
new file mode 100755
index 0000000000..df8c652043
--- /dev/null
+++ b/challenge-249/jo-37/perl/ch-1.pl
@@ -0,0 +1,62 @@
+#!/usr/bin/perl -s
+
+use v5.24;
+use Test2::V0;
+
+our ($tests, $examples);
+
+run_tests() if $tests || $examples; # does not return
+
+die <<EOS unless @ARGV;
+usage: $0 [-examples] [-tests] [N...]
+
+-examples
+ run the examples from the challenge
+
+-tests
+ run some tests
+
+N...
+ list of numbers
+
+EOS
+
+
+### Input and Output
+
+say join ", ", map "(@$_)", equal_pairs(@ARGV);
+
+
+### Implementation
+
+# Count the frequencies of all given numbers, check if these are all
+# even and build equal pairs.
+
+sub equal_pairs {
+ my %freq;
+ $freq{$_}++ for @_;
+ return () if grep $_ % 2, values %freq;
+
+ map +([$_, $_]) x ($freq{$_} / 2), keys %freq;
+}
+
+
+### Examples and tests
+
+sub run_tests {
+ SKIP: {
+ skip "examples" unless $examples;
+
+ is [equal_pairs(3, 2, 3, 2, 2, 2)],
+ bag {item [2, 2]; item [2, 2]; item [3, 3]; end;}, 'example 1';
+
+ is [equal_pairs(1, 2, 3, 4)], [] , 'example 2';
+ }
+
+ SKIP: {
+ skip "tests" unless $tests;
+ }
+
+ done_testing;
+ exit;
+}
diff --git a/challenge-249/jo-37/perl/ch-2.pl b/challenge-249/jo-37/perl/ch-2.pl
new file mode 100755
index 0000000000..4d440602ff
--- /dev/null
+++ b/challenge-249/jo-37/perl/ch-2.pl
@@ -0,0 +1,83 @@
+#!/usr/bin/perl -s
+
+use v5.24;
+use Test2::V0;
+
+our ($tests, $examples);
+
+run_tests() if $tests || $examples; # does not return
+
+die <<EOS unless @ARGV;
+usage: $0 [-examples] [-tests] [DI]
+
+-examples
+ run the examples from the challenge
+
+-tests
+ run some tests
+
+DI
+ a string consisting of 'D's and 'I's
+
+EOS
+
+
+### Input and Output
+
+say "(@{[arrange_di(shift)]})";
+
+
+### Implementation
+
+# First we transform the DI-string into an array of zeroes and ones
+# where a zero represents a decrement and a one an increment. Lets
+# assume the DI-string and the corresponding array have a length of L,
+# there are ND 'D's / zeroes and NI 'I's / ones.
+# Then we create two sequences:
+# - SD as the numbers 0 .. ND - 1 in descending order
+# - SI the numbers ND .. L - 1 in ascending order.
+# It can be seen that:
+# - Every element of SI is larger than any element of SD.
+# - Every element of SD is smaller than any element of SI.
+# - Every but the last element of SI is smaller than its successor.
+# - Every but the last element of DI is larger than its successor.
+# Now we can construct a permutation with the required incremental /
+# decremental behaviour by successively picking the first element from
+# the corresponding sequence - except for the very first.
+# The first element of our permutation may be chosen as follows:
+# - If the first step is a decrement, we just take L as the first
+# element.
+# - Otherwise, we pick the first element from the incremental sequence SI
+# and append L to SI
+
+sub arrange_di {
+ my @di = map tr/DI/01/r, split //, shift;
+ my @count = (0, 0);
+ $count[$_]++ for @di;
+ my @pool = ([reverse 0 .. $count[0] - 1], [$count[0] .. $#di]);
+
+ ($di[0] ?
+ do {push $pool[1]->@*, scalar @di; shift $pool[1]->@*} :
+ scalar @di,
+ map shift $pool[$_]->@*, @di);
+}
+
+
+### Examples and tests
+
+sub run_tests {
+ SKIP: {
+ skip "examples" unless $examples;
+
+ is [arrange_di('IDID')], [2, 3, 1, 4, 0], 'example 1';
+ is [arrange_di('III')], [0, 1, 2, 3], 'example 2';
+ is [arrange_di('DDI')], [3, 1, 0, 2], 'example 3';
+ }
+
+ SKIP: {
+ skip "tests" unless $tests;
+ }
+
+ done_testing;
+ exit;
+}