Perl Weekly Challenge 313.

My solutions (task 1 and task 2 ) to the The Weekly Challenge - 313.

Task 1: Broken Keys

Submitted by: Mohammad Sajid Anwar
You have a broken keyboard which sometimes type a character more than once.

You are given a string and actual typed string.

Write a script to find out if the actual typed string is meant for the given string.

Example 1
Input: $name = "perl", $typed = "perrrl"
Output: true

Here "r" is pressed 3 times instead of 1 time.
Example 2
Input: $name = "raku", $typed = "rrakuuuu"
Output: true
Example 3
Input: $name = "python", $typed = "perl"
Output: false
Example 4
Input: $name = "coffeescript", $typed = "cofffeescccript"
Output: true

I can build a regular expression based on the expected string by including one or more repetitions of each letter (appending a ‘+’) and then I can test the typed string against the expression. This yields a one-liner.

Examples:

perl -E '
for my ($n,$t)(@ARGV){($e=$n)=~s/(.)/$1+/g;say "$n, $t -> ", $t=~/$e/?"t":"f"}
' raku rrakuuu python perl coffeescript cofffeescccript

Results:

raku, rrakuuu -> t
python, perl -> f
coffeescript, cofffeescccript -> t

The full code is the same, with a couple of tests:

 1  # Perl weekly challenge 313
 2  # Task 1:  Broken Keys
 3  #
 4  # See https://wlmb.github.io/2025/03/17/PWC313/#task-1-broken-keys
 5  use v5.40;
 6  die <<~"FIN" unless @ARGV and @ARGV%2==0;
 7      Usage: $0 S1 T1 S2 T2...
 8      to check if the strings Tn typed in a broken typewriter
 9      correspond to the actual expected strings Sn.
10      FIN
11  for my($name, $typed)(@ARGV){
12      try {
13          die "Only word letters allowed: $name" unless $name=~/^\w+$/;
14          my $expression=$name;
15          $expression=~s/(.)/$1+/g;
16          my $result=($typed=~/$expression/)?"True":"False";
17          say "name=$name, typed=$typed -> $result";
18      }
19      catch($e){
20          say $e;
21      }
22  }

Example:

./ch-1.pl raku rrakuuu python perl coffeescript cofffeescccript

Results:

name=raku, typed=rrakuuu -> True
name=python, typed=perl -> False
name=coffeescript, typed=cofffeescccript -> True

Task 2: Reverse Letters

Submitted by: Mohammad Sajid Anwar
You are given a string.

Write a script to reverse only the alphabetic characters in the string.

Example 1
Input: $str = "p-er?l"
Output: "l-re?p"
Example 2
Input: $str = "wee-k!L-y"
Output: "yLk-e!e-w"
Example 3
Input: $str = "_c-!h_all-en!g_e"
Output: "_e-!g_nel-la!h_c"

I can extract the alphabetic letters and merge into the original string in the reverse order. I use the fact that when I iterate over an array, modifying the topic $_ modifies the actual array element. I assume ASCII letters. This yields a oneliner.

Examples:

perl -E '
for(@ARGV){@a=grep {/[a-zA-Z]/}@s=split "";$_=pop @a for grep {/[a-zA-Z]/}@s; say "$_ -> ", @s;}
' p-er?l wee-k!L-y _c-!h_all-en!g_e

Results:

p-er?l -> l-re?p
wee-k!L-y -> yLk-e!e-w
_c-!h_all-en!g_e -> _e-!g_nel-la!h_c

For the full code I use the POSIX alpha class.

 1  # Perl weekly challenge 313
 2  # Task 2:  Reverse Letters
 3  #
 4  # See https://wlmb.github.io/2025/03/17/PWC313/#task-2-reverse-letters
 5  use v5.36;
 6  die <<~"FIN" unless @ARGV;
 7      Usage: $0 S1 S2...
 8      to reverse the alphabetic letters within the strings Sn
 9      FIN
10  for(@ARGV){
11      my @letters=grep {/[[:alpha:]]/} my @characters=split "";
12      $_=pop @letters # modifies @characters
13          for grep {/[[:alpha:]]/} @characters;
14      my $output=join "", @characters;
15      say "$_ -> $output"
16  }

Example:

./ch-2.pl p-er?l wee-k!L-y _c-!h_all-en!g_e

Results:

p-er?l -> l-re?p
wee-k!L-y -> yLk-e!e-w
_c-!h_all-en!g_e -> _e-!g_nel-la!h_c

/;

Written on March 17, 2025