aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Sommrey <28217714+jo-37@users.noreply.github.com>2022-11-11 17:01:29 +0100
committerJörg Sommrey <28217714+jo-37@users.noreply.github.com>2022-11-11 17:01:29 +0100
commit8224bc4cb7938ea1c202dcff0a56b0847f573dd2 (patch)
treefc103cb24348e0e4994db93a699fdf1c608d1fe1
parent78a97ea8621c3fc04c65bc6f5104b247f5601095 (diff)
parent34e5fcc62c3a6e004e774fdf6d2c99310d18e533 (diff)
downloadperlweeklychallenge-club-8224bc4cb7938ea1c202dcff0a56b0847f573dd2.tar.gz
perlweeklychallenge-club-8224bc4cb7938ea1c202dcff0a56b0847f573dd2.tar.bz2
perlweeklychallenge-club-8224bc4cb7938ea1c202dcff0a56b0847f573dd2.zip
Solutions to challenge 190
-rwxr-xr-xchallenge-190/jo-37/perl/ch-1.pl67
-rwxr-xr-xchallenge-190/jo-37/perl/ch-2.pl97
2 files changed, 164 insertions, 0 deletions
diff --git a/challenge-190/jo-37/perl/ch-1.pl b/challenge-190/jo-37/perl/ch-1.pl
new file mode 100755
index 0000000000..d191a344c2
--- /dev/null
+++ b/challenge-190/jo-37/perl/ch-1.pl
@@ -0,0 +1,67 @@
+#!/usr/bin/perl -s
+
+use v5.16;
+use Test2::V0;
+
+our ($tests, $examples);
+
+run_tests() if $tests || $examples; # does not return
+
+die <<EOS unless @ARGV;
+usage: $0 [-examples] [-tests] [STR]
+
+-examples
+ run the examples from the challenge
+
+-tests
+ run some tests
+
+STR
+ String to check for appropriate capital usage
+
+EOS
+
+
+### Input and Output
+
+say 0 + !!check_caps(shift);
+
+
+### Implementation
+
+# There is no need to restrict this task to ASCII letters. For Unicode
+# characters there are properties "Letter uppercase" and "Letter
+# lowercase". Using these here.
+sub check_caps {
+ shift =~ /^\p{Lu}?(?:\p{Lu}*|\p{Ll}*)$/;
+}
+
+
+### Examples and tests
+
+sub run_tests {
+ SKIP: {
+ skip "examples" unless $examples;
+
+ ok check_caps('Perl'), 'Example 1';
+ ok check_caps('TPF'), 'Example 2';
+ ok !check_caps('PyThon'), 'Example 3';
+ ok check_caps('raku'), 'Example 4';
+ }
+
+ SKIP: {
+ skip "tests" unless $tests;
+
+ ok check_caps('Περλ'), 'Example 1 greek';
+ ok check_caps('ΤΠΦ'), 'Example 2 greek';
+ ok !check_caps('ΠυΘων'), 'Example 3 greek';
+ ok check_caps('ρακου'), 'Example 4 greek';
+ ok check_caps('Π'), 'single uppercase';
+ ok check_caps('ρ'), 'single lowercase';
+ ok !check_caps('1etter'), 'not a letter';
+
+ }
+
+ done_testing;
+ exit;
+}
diff --git a/challenge-190/jo-37/perl/ch-2.pl b/challenge-190/jo-37/perl/ch-2.pl
new file mode 100755
index 0000000000..185ebd1406
--- /dev/null
+++ b/challenge-190/jo-37/perl/ch-2.pl
@@ -0,0 +1,97 @@
+#!/usr/bin/perl -s
+
+use v5.16;
+use Test2::V0;
+
+our ($tests, $examples);
+
+run_tests() if $tests || $examples; # does not return
+
+die <<EOS unless @ARGV;
+usage: $0 [-examples] [-tests] [CODE]
+
+-examples
+ run the examples from the challenge
+
+-tests
+ run some tests
+
+CODE
+ code sequence
+
+EOS
+
+
+### Input and Output
+
+say for decode(shift);
+
+
+### Implementation
+
+# We have an encoding from letters starting with A, B, C, D to codes 1,
+# 2, 3, 4. The end of the sequence is not specified by the task's
+# description, but from example 3 it becomes clear that the sequence
+# ends with Z. Otherwise there would be a decoding for 27.
+#
+# A valid encoding thus must be matched by
+# /^(?:[1-9]|1[0-9]|2[0-6])+$/
+# Capturing and recording the internal matches and forcing the regex
+# engine into backtracking reveals all possible partitions of the
+# encoding.
+
+sub decode {
+ my @part;
+ our @p;
+
+ # Split the encoding into all possible partitions:
+ shift =~ m{
+ ^
+ (?| ([1-9]) (?&REC) # Process a matching branch, see below.
+ | (1[0-9]) (?&REC)
+ | (2[0-6]) (?&REC)
+ )+
+ $
+ (?{push @part, [@p]}) # Persist a complete partition.
+ (*FAIL) # Force backtracking.
+
+ (?(DEFINE) # Define
+ (?<REC> # a capture group named "REC" as:
+ (?{local @p = @p; push @p, $1})
+ # Create a backtracking-safe copy of the
+ # current (incomplete) partition and
+ # record the previously captured part of
+ # the string.
+ )
+ )
+ }x;
+
+ # Loop over the found partitions and convert the codes into their
+ # corresponding encoded ASCII characters.
+ map {pack 'C*', map ord('A') + $_ - 1, @$_} @part;
+}
+
+
+### Examples and tests
+
+sub run_tests {
+ SKIP: {
+ skip "examples" unless $examples;
+
+ is [decode(11)], [qw(AA K)], 'Example 1';
+ is [decode(1115)], [qw(AAAE AAO AKE KAE KO)], 'Example 2';
+ is [decode(127)], [qw(ABG LG)], 'Example 3';
+
+ }
+
+ SKIP: {
+ skip "tests" unless $tests;
+
+ is decode(130), F(), 'invalid zero';
+ is [decode(120)], ['AT'], 'valid zero';
+ is [decode(3 x 128)], ['C' x 128], 'long code';
+ }
+
+ done_testing;
+ exit;
+}