Task 1: Upper Lower
You are given a string consisting of English letters only.
Write a script to convert lower case to upper and upper case to lower in the given string.
Example 1
Input: $str = "pERl"
Output: "PerL"
Example 2
Input: $str = "rakU"
Output: "RAKu"
Example 3
Input: $str = "PyThOn"
Output: "pYtHoN"
Logic
This is a straightforward character-level transformation:
- Iterate over each character in the string.
- If the character is lowercase, convert it to uppercase.
- If the character is uppercase, convert it to lowercase.
- Return the resulting string.
In Perl, this is elegantly done with the tr/// (transliteration) operator: $str =~ tr/a-zA-Z/A-Za-z/. In Python, we use a generator expression with str.swapcase() or manual isupper()/islower() checks.
Perl Solution
ch-1.pl
#!/usr/bin/env perl
use v5.38;
use warnings;
use feature 'signatures';
no warnings 'experimental::signatures';
## no critic (Subroutines::ProhibitSubroutinePrototypes)
use Type::Params qw(compile);
use Types::Standard qw(Str);
my $STR_CHECK = compile(Str);
sub upper_lower ($str) {
($str) = $STR_CHECK->($str);
$str =~ tr/a-zA-Z/A-Za-z/;
return $str;
}
Python Solution
ch-1.py
#!/usr/bin/env python3
"""Upper Lower - Perl Weekly Challenge 311 task 1."""
from __future__ import annotations
from collections.abc import Sequence
import sys
import unittest
def upper_lower(text: str) -> str:
"""Swap case of each alphabetic character."""
return "".join(ch.lower() if ch.isupper() else ch.upper() for ch in text)
class UpperLowerExamples(unittest.TestCase):
"""Example-based tests from the specification."""
def test_example_1(self) -> None:
self.assertEqual(upper_lower("pERl"), "PerL")
def test_example_2(self) -> None:
self.assertEqual(upper_lower("rakU"), "RAKu")
def test_example_3(self) -> None:
self.assertEqual(upper_lower("PyThOn"), "pYtHoN")
Task 2: Group Digit Sum
You are given a string, $str, made up of digits, and an integer, $int, which is less than the length of the given string.
Write a script to divide the given string into consecutive groups of size $int (plus one for leftovers if any). Then sum the digits of each group, and concatenate all group sums to create a new string. If the length of the new string is less than or equal to the given integer then return the new string, otherwise continue the process.
Example 1
Input: $str = "111122333", $int = 3
Output: "359"
Step 1: "111", "122", "333" => "359"
Example 2
Input: $str = "1222312", $int = 2
Output: "76"
Step 1: "12", "22", "31", "2" => "3442"
Step 2: "34", "42" => "76"
Example 3
Input: $str = "100012121001", $int = 4
Output: "162"
Step 1: "1000", "1212", "1001" => "162"
Logic
To compute the group digit sum:
- Split the digit string into consecutive groups of size
$int. The last group may be shorter.
- Sum the digits within each group.
- Concatenate all the sums (as strings) to form a new string.
- If the new string's length is less than or equal to
$int, return it.
- Otherwise, repeat the process with the new string.
The process always terminates because each iteration reduces the string length (since the sum of digits in a group of size N is at most 9N, which has fewer digits than N for N ≥ 2).
Perl Solution
ch-2.pl
#!/usr/bin/env perl
use v5.38;
use warnings;
use feature 'signatures';
no warnings 'experimental::signatures';
## no critic (Subroutines::ProhibitSubroutinePrototypes)
use Type::Params qw(compile);
use Types::Standard qw(Int Str);
my $ARGS_CHECK = compile( Str, Int );
sub _sum_digits ($chunk) {
my $sum = 0;
$sum += $_ for split //, $chunk;
return $sum;
}
sub group_digit_sum ($str, $int) {
( $str, $int ) = $ARGS_CHECK->( $str, $int );
die 'Expected $int > 0' if $int <= 0;
die 'Expected digits only' if $str =~ /[^0-9]/;
while ( length($str) > $int ) {
my @parts;
for ( my $i = 0; $i < length($str); $i += $int ) {
push @parts, substr( $str, $i, $int );
}
$str = join '', map { _sum_digits($_) } @parts;
}
return $str;
}
Python Solution
ch-2.py
#!/usr/bin/env python3
"""Group Digit Sum - Perl Weekly Challenge 311 task 2."""
from __future__ import annotations
from collections.abc import Sequence
import sys
import unittest
def _sum_digits(chunk: str) -> int:
return sum(int(ch) for ch in chunk)
def group_digit_sum(text: str, size: int) -> str:
"""
Repeatedly sum digits in consecutive groups of ``size`` and concatenate sums.
Stop once the new string length is <= ``size``.
"""
if size <= 0:
raise ValueError("Expected size > 0")
if not text.isdigit():
raise ValueError("Expected digits only")
while len(text) > size:
parts = [text[idx : idx + size] for idx in range(0, len(text), size)]
text = "".join(str(_sum_digits(part)) for part in parts)
return text
class GroupDigitSumExamples(unittest.TestCase):
"""Example-based tests from the specification."""
def test_example_1(self) -> None:
self.assertEqual(group_digit_sum("111122333", 3), "359")
def test_example_2(self) -> None:
self.assertEqual(group_digit_sum("1222312", 2), "76")
def test_example_3(self) -> None:
self.assertEqual(group_digit_sum("100012121001", 4), "162")