diff --git a/challenge-313/jo-37/blog.txt b/challenge-313/jo-37/blog.txt new file mode 100644 index 0000000000..eb7adbdb33 --- /dev/null +++ b/challenge-313/jo-37/blog.txt @@ -0,0 +1 @@ +https://github.sommrey.de/the-bears-den/2025/03/21/ch-313.html diff --git a/challenge-313/jo-37/perl/ch-1.pl b/challenge-313/jo-37/perl/ch-1.pl new file mode 100755 index 0000000000..5b0aa1117d --- /dev/null +++ b/challenge-313/jo-37/perl/ch-1.pl @@ -0,0 +1,93 @@ +#!/usr/bin/perl + +use v5.26; +use Test2::V0 -no_srand; +use Test2::Tools::Subtest 'subtest_streamed'; +use Getopt::Long; +use experimental 'signatures'; + +### Options and Arguments + +my ($tests, $examples, $verbose); +GetOptions( + 'examples!' => \$examples, + 'tests!' => \$tests, + 'verbose!' => \$verbose, +) or usage(); + +run_tests($examples, $tests); # tests do not return + +usage() unless @ARGV == 2; + +sub usage { + die <<~EOS; + $0 - check broken keys + + usage: $0 [-examples] [-tests] [--] [NAME TYPED] + + -examples + run the examples from the challenge + + -tests + run some tests + + NAME + the original string + + TYPED + the typed string + + EOS +} + + +### Input and Output + +say +(qw(true false))[!broken_keys(@ARGV)]; + + +### Implementation +# +# For details see: +# https://github.sommrey.de/the-bears-den/2025/03/21/ch-313.html#task-1 + + +sub broken_keys ($name, $typed) { + $typed =~ /^(??{$name =~ s#.#\Q$&\E+#gr})$/; +} + + +### Examples and Tests + +sub run_tests ($examples, $tests) { + return unless $examples || $tests; + + state sub run_example ($args, $expected, $name) { + my $result = broken_keys(@$args); + is $result, $expected, + "$name: (@$args) -> " . $expected->name; + } + + plan 2; + + $examples ? subtest_streamed(examples => sub { + my @examples = ( + [['perl', 'perrrl'], T(), 'example 1'], + [['raku', 'rrakuuuu'], T(), 'example 2'], + [['python', 'perl'], F(), 'example 3'], + [['coffeescript', 'cofffeescccript'], T(), 'example 4'], + ); + plan scalar @examples; + for (@examples) { + run_example @$_; + } + }) : pass 'skip examples'; + + $tests ? subtest_streamed(tests => sub { + plan 2; + is broken_keys('.', 'abc'), F(), 'ignore regex meta'; + is broken_keys('+*', '++**'), T(), 'match regex meta'; + }) : pass 'skip tests'; + + exit; +} diff --git a/challenge-313/jo-37/perl/ch-2.pl b/challenge-313/jo-37/perl/ch-2.pl new file mode 100755 index 0000000000..cf73e74c6c --- /dev/null +++ b/challenge-313/jo-37/perl/ch-2.pl @@ -0,0 +1,94 @@ +#!/usr/bin/perl + +use v5.26; +use Test2::V0 -no_srand; +use Test2::Tools::Subtest 'subtest_streamed'; +use Getopt::Long; +use experimental 'signatures'; + +use List::MoreUtils 'indexes'; + +### Options and Arguments + +my ($tests, $examples, $verbose); +GetOptions( + 'examples!' => \$examples, + 'tests!' => \$tests, + 'verbose!' => \$verbose, +) or usage(); + +run_tests($examples, $tests); # tests do not return + +usage() unless @ARGV == 1; + +sub usage { + die <<~EOS; + $0 - Task Title + + usage: $0 [-examples] [-tests] [STR] + + -examples + run the examples from the challenge + + -tests + run some tests + + STR + a string + + EOS +} + + +### Input and Output + +say reverse_letters(shift); + + +### Implementation +# +# For details see: +# https://github.sommrey.de/the-bears-den/2025/03/21/ch-313.html#task-2 + + +sub reverse_letters { + my @s = shift =~ /\X/g; + my @li = indexes {/\p{L}/} @s; + @s[@li] = @s[reverse @li]; + join '', @s; +} + + +### Examples and Tests + +sub run_tests ($examples, $tests) { + return unless $examples || $tests; + + state sub run_example ($args, $expected, $name) { + my $result = reverse_letters(@$args); + is $result, $expected, + "$name: (@$args) -> $expected"; + } + + plan 2; + + $examples ? subtest_streamed(examples => sub { + my @examples = ( + [["p-er?l"], "l-re?p", 'example 1'], + [["wee-k!L-y"], "yLk-e!e-w", 'example 2'], + [["_c-!h_all-en!g_e"], "_e-!g_nel-la!h_c", 'example 3'], + ); + plan scalar @examples; + for (@examples) { + run_example @$_; + } + }) : pass 'skip examples'; + + $tests ? subtest_streamed(tests => sub { + plan 1; + is reverse_letters("a\N{COMBINING DIAERESIS},o&u"), + "u,o&a\N{COMBINING DIAERESIS}", 'operate on grapheme clusters'; + }) : pass 'skip tests'; + + exit; +}