17 October 2025 | Challenge 342 |
Balanced Score
Task 1: Balance String
Submitted by: Mohammad Sajid Anwar
You are given a string made up of lowercase English letters and digits only.
Write a script to format the give string where no letter is followed by another letter and no digit is followed by another digit. If there are multiple valid rearrangements, always return the lexicographically smallest one. Return empty string if it is impossible to format the string.
Example 1
Input: $str = "a0b1c2"
Output: "0a1b2c"
Example 2
Input: $str = "abc12"
Output: "a1b2c"
Example 3
Input: $str = "0a2b1c3"
Output: "0a1b2c3"
Example 4
Input: $str = "1a23"
Output: ""
Example 5
Input: $str = "ab123"
Output: "1a2b3"
Solution
The string is split into individual characters, these are sorted and partitioned into digits and non-digits. If the numbers of digits and non-digits differ by more than one, the string cannot be balanced.
Otherwise the two parts are mesh
‘ed together and joined in the length of the original string.
Unless there are more non-digits than digits, the balanced string starts with a digit.
use v5.24;
use warnings;
use experimental 'signatures';
use List::Util 'mesh';
use List::MoreUtils 'part';
sub balance_string ($str) {
my @parts = part {/\D/} sort split //, $str;
my $ld = $parts[1]->@* - $parts[0]->@*;
return '' if abs $ld > 1;
join '', (mesh $ld > 0 ? reverse @parts : @parts)[0 .. length($str) - 1];
}
See the full solution to task 1.
Task 2: Max Score
Submitted by: Mohammad Sajid Anwar
You are given a string, $str
, containing 0
and 1
only.
Write a script to return the max score after splitting the string into two non-empty substrings. The score after splitting a string is the number of zeros in the left substring plus the number of ones in the right substring.
Example 1
Input: $str = "0011"
Output: 4
1: left = "0", right = "011" => 1 + 2 => 3
2: left = "00", right = "11" => 2 + 2 => 4
3: left = "001", right = "1" => 2 + 1 => 3
Example 2
Input: $str = "0000"
Output: 3
1: left = "0", right = "000" => 1 + 0 => 1
2: left = "00", right = "00" => 2 + 0 => 2
3: left = "000", right = "0" => 3 + 0 => 3
Example 3
Input: $str = "1111"
Output: 3
1: left = "1", right = "111" => 0 + 3 => 3
2: left = "11", right = "11" => 0 + 2 => 2
3: left = "111", right = "1" => 0 + 1 => 1
Example 4
Input: $str = "0101"
Output: 3
1: left = "0", right = "101" => 1 + 2 => 3
2: left = "01", right = "01" => 1 + 1 => 2
3: left = "010", right = "1" => 2 + 1 => 3
Example 5
Input: $str = "011101"
Output: 5
1: left = "0", right = "11101" => 1 + 4 => 5
2: left = "01", right = "1101" => 1 + 3 => 4
3: left = "011", right = "101" => 1 + 2 => 3
4: left = "0111", right = "01" => 1 + 1 => 2
5: left = "01110", right = "1" => 2 + 1 => 3
Solution
Building an array from the binary digits.
The number of zeroes in a heading substring can be found as the cumulative sum over 1 - b
and the number of ones in a trailing substring as the reverse cumulative sum over b
.
The maximum of the sum of both lists is the requested maximum score.
use strict;
use warinings;
use PDL;
use PDL::NiceSlice;
sub max_score {
my $bin = long split //, shift;
max +(1 - $bin)->(0:-2)->cumusumover + $bin(-1:1)->cumusumover->(-1:0);
}
See the full solution to task 2.
If you have a question about this post or if you like to comment on it, feel free to open an issue in my github repository.