Task 1: Balance String
"Letters and Digits: Alternate or Bust!"
Given a string of lowercase letters and digits, rearrange it so no letter follows another letter and no digit follows another digit. Return the lexicographically smallest such arrangement, or an empty string if impossible.
The Strategy: Separate and sort letters and digits. If the counts differ by more than 1, no valid arrangement exists. Otherwise, interleave starting with whichever type is more numerous. When counts are equal, start with digits for the smallest lexicographic result.
Perl Implementation
sub balance_string {
my ($str) = @_;
my @letters = sort grep /[a-z]/, split //, $str;
my @digits = sort grep /\d/, split //, $str;
my $diff = @letters - @digits;
return "" if $diff > 1 || $diff < -1;
my @result;
my ( $i, $j ) = ( 0, 0 );
if ( @letters > @digits ) {
while ( $i < @letters || $j < @digits ) {
push @result, $letters[$i] if $i < @letters;
$i++;
push @result, $digits[$j] if $j < @digits;
$j++;
}
} else {
while ( $i < @letters || $j < @digits ) {
push @result, $digits[$j] if $j < @digits;
$j++;
push @result, $letters[$i] if $i < @letters;
$i++;
}
}
return join "", @result;
}
Python Implementation
def balance_string(text: str) -> str:
"""Rearrange so letters and digits alternate. Lex smallest or empty."""
letters = sorted(ch for ch in text if ch.isalpha())
digits = sorted(ch for ch in text if ch.isdigit())
if abs(len(letters) - len(digits)) > 1:
return ""
result = []
i = j = 0
if len(letters) > len(digits):
while i < len(letters) or j < len(digits):
if i < len(letters):
result.append(letters[i]); i += 1
if j < len(digits):
result.append(digits[j]); j += 1
else:
while i < len(letters) or j < len(digits):
if j < len(digits):
result.append(digits[j]); j += 1
if i < len(letters):
result.append(letters[i]); i += 1
return "".join(result)