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
/;