cd /news/developer-tools/weekly-challenge-rearranging-atoms · home topics developer-tools article
[ARTICLE · art-107742] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

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.

read3 min views1 publishedAug 23, 2026

Each week Mohammad S. Anwar sends out The Weekly Challenge, 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.

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]

.

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.

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
── more in #developer-tools 4 stories · sorted by recency
── more on @mohammad s. anwar 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/weekly-challenge-rea…] indexed:0 read:3min 2026-08-23 ·