Perl Weekly Challenge 387.

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

Task 1: Rearrange Binary String

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

Write a script to re-arrange the given binary string that
all occurrences of “01” are simultaneously replaced with
“10” until no occurrences of “01” exist. Finally return the
total steps needed.

Example 1
Input: $str = "111000"
Output: 0

The string already has all 1s on the left and 0s on the right.
There are no occurrences of "01", so zero step needed.

Example 2
Input: $str = "00011"
Output: 4

Step 1: "00101"
Step 2: "01010"
Step 3: "10100"
Step 4: "11000"

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

Step 1: "10101"
Step 2: "11010"
Step 3: "11100"

Example 4
Input: $str = "010101"
Output: 3

Step 1: "101010"
Step 2: "110100"
Step 3: "111000"

Example 5
Input: $str = "00001"
Output: 4

Step 1: "00010"
Step 2: "00100"
Step 3: "01000"
Step 4: "10000"

A very simple solution consists on applying the transformation until no longer possible and count the number of operations. This yields a 1-liner.

perl -E '
for(@ARGV){$i=$_; $c=0; ++$c while s/01/10/g; say "$i -> $c"}
' 111000 00011 01011 010101 00001

The /g flag makes as many transpositions in parallel as possible.

Results:

111000 -> 0
00011 -> 4
01011 -> 3
010101 -> 3
00001 -> 4

I guess there is a more sophisticated solution based on counting the sizes of groups of consecutive 0’s and consecutive 1’s and performing some calculation, but there are too many cases to consider, so I gave up.

The full code is:

 1  # Perl weekly challenge 387
 2  # Task 1:  Reverse Base
 3  #
 4  # See https://wlmb.github.io/2026/08/17/PWC387/#task-1-rearrenge-binary-string
 5  use v5.36;
 6  use feature qw(try);
 7  die <<~"FIN" unless @ARGV;
 8      Usage: $0 B0 B1...
 9      to find hao many transpositions of 01 have to be done in parallel
10      to order all 1's before all 0's inbinary string Bn
11      FIN
12  for(@ARGV){
13      try{
14          die "Expected binary string: $_" unless /^(0|1)+$/;
15          my $in=$_;
16          my $count=0;
17          ++$count while s/01/10/g;
18          say "$in -> $count"
19      }
20      catch($e){warn $e}
21  }

Example:

./ch-1.pl  111000 00011 01011 010101 00001

Results:

111000 -> 0
00011 -> 4
01011 -> 3
010101 -> 3
00001 -> 4

Task 2: Chemical formulae

Submitted by: Mohammad Sajid Anwar
You are given a chemical formula with elements, numbers, and parentheses.

Write a script to count the total number of each type of
atom by expanding all grouped multipliers. Then, format and
return the final inventory as a single string sorted
alphabetically by element name, including the total count
only if it is greater than 1.

Example 1
Input: $formula = "((N2O)3(H2O)2)2"
Output: "H8N12O10"

Step 1: Expand the innermost parentheses
    (N2O)3 => N = 2*3 = 6, O = 1*3 = 3 => N6O3
    (H2O)2 => H = 2*2 = 4, O = 1*2 = 2 => H4O2

Step 2: Combine inside the outer parentheses
    Formula becomes: (N6O3 H4O2)2
    Sum up identical elements inside: (N6 H4 O5)2

Step 3: Apply the outer multiplier
    N = 6*2 = 12
    H = 4*2 = 8
    O = 5*2 = 10

Step 4: Sort alphabetically and format
    Alphabetical order: H, N, O
    Counts: H: 8, N: 12, O: 10

Example 2
Input: $formula = "Mg3(PO4)2"
Output: "Mg3O8P2"

Step 1: Parse ungrouped elements
    Mg3 => Mg = 3

Step 2: Expand parentheses (PO4)2
    P = 1*2 = 2
    O = 4*2 = 8

Step 3: Total up counts
    Mg = 3
    P  = 2
    O  = 8

Step 4: Sort alphabetically and format
    Alphabetical order: Mg, O, P
    Counts: Mg: 3, O: 8, P: 2

Example 3
Input: $formula = "(((H)2)3)4"
Output: "H24"

Step 1: Expand innermost level (H)2
    H = 1*2 = 2 => formula becomes ((H2)3)4

Step 2: Expand middle level (H2)3
    H = 2*3 = 6 => formula becomes (H6)4

Step 3: Expand outer level (H6)4
    H = 6*4 = 24

Step 4: Sort alphabetically and format
    Single element: H: 24

Example 4
Input: $formula = "NaCl3(O2(S10)2)2Mg"
Output: "Cl3MgNaO4S40"

Step 1: Expand innermost parentheses (S10)2
    S = 10*2 = 20 => inner formula becomes => O2S20

Step 2: Expand outer parentheses (O2S20)2
    O = 2*2  = 4
    S = 20*2 = 40

Step 3: Combine all parts
    Ungrouped start: Na (Na = 1), Cl3 (Cl = 3)
    Expanded middle: O = 4, S = 40
    Ungrouped end: Mg (Mg = 1)

Step 4: Sort alphabetically and format
    Alphabetical order: Cl (3), Mg (1), Na (1), O (4), S (40)
    Omit the number 1 for Mg and Na.

Example 5
Input: $formula = "Z2Y3(X2W)2"
Output: "W2X4Y3Z2"

Step 1: Parse ungrouped elements
    Z2 => Z = 2
    Y3 => Y = 3

Step 2: Expand parentheses (X2W)2
    X = 2*2 = 4
    W = 1*2 = 2

Step 3: Total up counts
    W = 2, X = 4, Y = 3, Z = 2

Step 4: Sort alphabetically and format
    Alphabetical order: W (2), X (4), Y (3), Z (2)

I use a recursive subroutine to parse the chemical formula and return the composition as a hash that maps element to count. I use Text::Balanced to parse nested parenthesized formulae, and multiply their composition by the repeat count.

 1  # Perl weekly challenge 387
 2  # Task 2:  Chemical formulae
 3  #
 4  # See https://wlmb.github.io/2026/08/17/PWC387/#task-2-chemical-formulae
 5  use v5.36;
 6  use Text::Balanced qw(extract_bracketed);
 7  use feature qw(try);
 8  
 9  die <<~"FIN" unless @ARGV;
10      Usage: $0 F0 F1...
11      to parse and simplify the chemical formula Fn removing
12      parenthesis
13      FIN
14  for(@ARGV){
15      try{
16          my %composition = parse($_, ());
17          $composition{$_}=""
18              for grep {$composition{$_}==1} keys %composition;
19          say "$_ -> ",
20              map {($_, $composition{$_})} sort keys %composition
21      }
22      catch($e){warn "Error in $_: $e"}
23  }
24  
25  sub parse($formula, %current){
26      for($formula){
27          while($_){
28              my $start=$_;
29              $current{$1} += $2||1
30                  if s/^([A-Z][a-z]*)(\d*)//; #found element
31              my ($subformula, $rest)=extract_bracketed;
32              if($subformula){
33                  my %subcomposition =
34                      parse(substr($subformula,1,
35                                   length($subformula)-2), ());
36                  $rest=~s/^(\d)*//;
37                  my $multiplier = $1 || 1;
38                  $current{$_} += $multiplier * $subcomposition{$_}
39                      for keys %subcomposition;
40                  $_ = $rest; # update topic
41              }
42              die "Malformed formula: $_" if $_ eq $start; # avoid infinite loop
43          }
44      }
45      return %current;
46  }

Example:

./ch-2.pl "((N2O)3(H2O)2)2" "Mg3(PO4)2" "(((H)2)3)4" \
          "NaCl3(O2(S10)2)2Mg" "Z2Y3(X2W)2"

Results:

((N2O)3(H2O)2)2 -> H8N12O10
Mg3(PO4)2 -> Mg3O8P2
(((H)2)3)4 -> H24
NaCl3(O2(S10)2)2Mg -> Cl3MgNaO4S40
Z2Y3(X2W)2 -> W2X4Y3Z2

/;

Written on August 17, 2026