Perl Weekly Challenge 328.

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

Task 1: Replace all ?

Submitted by: Mohammad Sajid Anwar
You are given a string containing only lower case English letters and ?.

Write a script to replace all ? in the given string so that the string
doesn’t contain consecutive repeating characters.


Example 1
Input: $str = "a?z"
Output: "abz"

There can be many strings, one of them is "abz".
The choices are 'a' to 'z' but we can't use either 'a' or 'z' to replace
the '?'.

Example 2
Input: $str = "pe?k"
Output: "peak"

Example 3
Input: $str = "gra?te"
Output: "grabte"

A simple straightforward solution is to replace ? with a, and increment it until it differs from the previous and next characters. I use the autoincrement operator acting on strings and the /e switch of the substitution operator, to allow arbitrary Perl expressions in the replacement, which yields a simple one+ liner.

Examples:

perl -E '
for(@ARGV){$i=$_;1while s/(.?)(\?)(.?)/do{$y="a";++$y while$y eq$1 or $y eq$3;"$1$y$3"}/e;say"$i->$_"}
' a?z pe?k gra?te

Results:

a?z -> abz
pe?k -> peak
gra?te -> grabte

Other examples: Examples:

perl -E '
for(@ARGV){$i=$_;1while s/(.?)(\?)(.?)/do{$y="a";++$y while$y eq$1 or $y eq$3;"$1$y$3"}/e;say"$i->$_"}
' a?a a?b a??a a??b a??c ?a a?

Results:

a?a->aba
a?b->acb
a??a->abca
a??b->abab
a??c->abac
?a->ba
a?->ab

The full code is similar, but with an explicit function to process the replacement and some tests.

 1  # Perl weekly challenge 328
 2  # Task 1:  Replace all ?
 3  #
 4  # See https://wlmb.github.io/2025/07/03/PWC328/#task-1-replace-all-?
 5  
 6  use v5.36;
 7  die <<~"FIN" unless @ARGV;
 8      Usage: $0 S1 S2...
 9      to replace ? by lowercase letters in the lowercase strings S1 S2...
10      so that no letter repeats.
11      FIN
12  for(@ARGV){
13      say "Expected only lowercase letters and ?'s" unless /^[a-z?]+$/;
14      say("Expected no repeating letters in string: $_"), next if /([a-z])\1/;
15      my $in=$_;
16      1 while s/(.?)(\?)(.?)/replace($1, $3)/e;
17      say "$in -> $_";
18  }
19  sub replace($x, $z){
20      my $y="a";
21      ++$y while $y eq $x or $y eq $z;
22      "$1$y$3"
23  }

Examples:

./ch-1.pl  a?z pe?k gra?te a?a a?b a??a a??b a??c ?a a?

Results:

a?z -> abz
pe?k -> peak
gra?te -> grabte
a?a -> aba
a?b -> acb
a??a -> abca
a??b -> abab
a??c -> abac
?a -> ba
a? -> ab

Task 2: Good String

Submitted by: Mohammad Sajid Anwar
You are given a string made up of lower and upper case English letters only.

Write a script to return the good string of the given string. A string is
called good string if it doesn’t have two adjacent same characters, one in
upper case and other is lower case.

UPDATE [2025-07-01]: Just to be explicit, you can only remove pair if they are
same characters, one in lower case and other in upper case, order is not important.


Example 1
Input: $str = "WeEeekly"
Output: "Weekly"

We can remove either, "eE" or "Ee" to make it good.

Example 2
Input: $str = "abBAdD"
Output: ""

We remove "bB" first: "aAdD"
Then we remove "aA": "dD"
Finally remove "dD".

Example 3
Input: $str = "abc"
Output: "abc"

This task may be easily solved by using Perl’s extended patterns. In particular, (??{ *code* }) allows running some code to build the regular expression to match. For example, the regular expression (.)(??{uc($1)}) matches a character followed by its uppercase counterpart. This allows a simple oneliner:

Examples:

perl -E '
for(@ARGV){$i=$_;1 while(s/(.)(??{$l=lc($1); $l eq $1? uc($1):lc($1)})//);say"$i->$_";}
' WeEeekly abBAdD abc

Results:

WeEeekly->Weekly
abBAdD->
abc->abc

Here I use the regular expression (.)(??{$l=lc($1); $l eq $1? uc($1):lc($1)}) which matches a lowercase character followed by its uppercase counterpart and an uppwercase character followed by its lowercase counterpart. As it is, it only works for alphabetical characters.

I test the code with the same examples but inverting the cases:

perl -E '
for(@ARGV){$i=$_;1 while(s/(.)(??{$l=lc($1); $l eq $1? uc($1):lc($1)})//);say"$i->$_";}
' wEeEEKLY ABbaDd ABC

Results:

wEeEEKLY->wEEKLY
ABbaDd->
ABC->ABC

Upper and lowercase non-alphabetical characters are equal, so it is not clear if they whould be deleted when repeated. The code above would delete them:

perl -E '
for(@ARGV){$i=$_;1 while(s/(.)(??{$l=lc($1); $l eq $1? uc($1):lc($1)})//);say"$i->$_";}
' 12aA23

Results:

12aA23->13

The full code is similar but I don’t delete pairs of repeated non-alphabetical characters:

 1  # Perl weekly challenge 328
 2  # Task 2:  Good String
 3  #
 4  # See https://wlmb.github.io/2025/07/03/PWC328/#task-2-good-string
 5  use v5.36;
 6  die <<~"FIN" unless @ARGV;
 7      Usage: $0 S1 S2...
 8      to convert the strings S1 S2... into good strings
 9      without any lowercase (uppercase) letter adjacent to the corresponding
10      uppercase (lowercase) letter.
11      FIN
12  for(@ARGV){
13      my $in=$_;
14      1 while(s/([[:alpha:]])(??{my $l=lc($1); $l eq $1? uc($1):lc($1)})//);
15      say"$in->$_";
16  }

Examples:

./ch-2.pl WeEeekly abBAdD abc wEeEEKLY ABbaDd ABC 12aA23

Results:

WeEeekly->Weekly
abBAdD->
abc->abc
wEeEEKLY->wEEKLY
ABbaDd->
ABC->ABC
12aA23->1223

/;

Written on July 3, 2025