Weekly Challenge: Rearranging Atoms A developer shared solutions to The Weekly Challenge's two tasks, implementing binary string rearrangement and chemical formula atom counting in Python and Perl. The binary string task replaces all occurrences of '01' with '10' until none remain, returning the number of steps. The chemical formula task expands parentheses and counts atoms, outputting a sorted inventory. Each week Mohammad S. Anwar sends out The Weekly Challenge https://theweeklychallenge.org/ , a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. Unless otherwise stated, Copilot and other AI tools have NOT been used to generate the solution. It's a great way for us all to practice some coding. 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. For this task, I have coded the instructions as stated. I have a variable count that counts the number of times the loop is run before the solution is found. php def rearrange binstr input string: str - int: if not re.search "^ 01 +$", input string : raise ValueError "Invalid input" count = 0 while "01" in input string: count += 1 input string = re.sub "01", "10", input string return count The Perl solution follows the same logic. sub main $input string { if $input string ~ /^ 01 +$/ { die "Invalid input\n"; } my $count = 0; while index $input string, "01" = -1 { $count++; $input string =~ s/01/10/g; } say $count; } $ ./ch-1.py 111000 0 $ ./ch-1.py 00011 4 $ ./ch-1.py 01011 3 $ ./ch-1.py 010101 3 $ ./ch-1.py 00001 4 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. For this task I start with a function called expand parens which will expand the inner most parentheses followed by a number using that number match obj 2 to multiple the number of atoms for each individual element match obj 1 . php def expand parens match obj: re.Match - str: multiplier = int match obj 2 new elements = defaultdict int for elements in re.findall r" A-Z a-z ? \d+ ?", match obj 1 : new elements elements 0 += int 1 if elements 1 == "" else elements 1 multiplier return "".join f"{key}{value}" for key, value in new elements.items The main atom count function starts by expanding all parentheses are expanded. php def atom count input string: str - str: while re.search r"\ A-Z0-9 +\ \d+", input string, flags=re.I : input string = re.sub r"\ A-Z0-9 + \ \d+ ", expand parens, input string, flags=re.I It then checks that the final string is as expected, in case the input has mismatched parentheses or symbols for example. if not re.search "^ A-Z0-9 +$", input string, flags=re.I : raise ValueError "Invalid input" The next step is to count the number of atoms each element has. count elements = defaultdict int for elements in re.findall r" A-Z a-z ? \d+ ?", input string : count elements elements 0 += int 1 if elements 1 == "" else elements 1 The final step is to convert this dict into a string sorted alphabetically by the element. If there is more than one atom, the number is appended as required. output = "" for element in sorted count elements : count = count elements element output += element if count 1: output += str count return output Like with the first task, the Perl solution follows the same logic. It uses the s///e pattern to call the expand parens function. $ ./ch-2.py " N2O 3 H2O 2 2" H8N12O10 $ ./ch-2.py "Mg3 PO4 2" Mg3O8P2 $ ./ch-2.py " H 2 3 4" H24 $ ./ch-2.py "NaCl3 O2 S10 2 2Mg" Cl3MgNaO4S40 $ ./ch-2.py "Z2Y3 X2W 2" W2X4Y3Z2