RabbitFarm

2025-03-08

Lower the Upper Sums!

The examples used here are from the weekly challenge problem statement and demonstrate the working solution.

Part 1: Upper Lower

You are given a string consists of english letters only. Write a script to convert lower case to upper and upper case to lower in the given string.

The complete solution is contained in one file that has a simple structure.

"ch-1.pl" 1


preamble 2
upper lower calculations 3
main 4

For this problem we do not need to include very much. We’re just specifying to use the current version of Perl, for all the latest features in the language. This fragment is also used in Part 2.

preamble 2 ⟩≡


use v5.38;

Fragment referenced in 1, 5.

All the work is in one subroutine. We use the ASCII values of each character to compute the new value.

upper lower calculations 3 ⟩≡


sub upper_lower{
my($s) = @_;
my @c = split //, $s;
return join q//, map{
my $x = ord($_);
if($x >= 65 && $x <= 90){
chr($x + 32);
}
elsif($x >= 97 && $x <= 122){
chr($x - 32);
}
} @c;
}

Fragment referenced in 1.

Now all we need are a few lines of code for running some tests.

main 4 ⟩≡


MAIN:{
say upper_lower q/pERl/;
say upper_lower q/rakU/;
say upper_lower q/PyThOn/;
}

Fragment referenced in 1.

Sample Run
$ perl perl/ch-1.pl 
PerL 
RAKu 
pYtHoN
    

Part 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.

"ch-2.pl" 5


preamble 2
group digit sum 9
main 10

To solve this problem we need to do the following

1.
divide the list into groups of the given size
2.
compute the sums
3.
recombine
4.
repeat as needed

Let’s look at each of those pieces individually and then combine them together into one subroutine.

divide the list into groups of the given size 6 ⟩≡


my $g = [];
my $groups;
for my $i (0 .. @{$c} - 1){
my $n = $i % $size;

if($n == 0){
$g = [];
push @{$g}, $c->[$i];
}
elsif($n == $size - 1){
push @{$g}, $c->[$i];
push @{$groups}, $g;
$g = [];
}
else{
push @{$g}, $c->[$i];
}
}
push @{$groups}, $g if @{$g} > 0;

Fragment referenced in 9.

Defines: $groups 7.

Uses: $c 9, $size 9.

compute the sums 7 ⟩≡


my $sums = [];
do{
my $sum = unpack(q/%32I*/, pack(q/I*/, @{$_}));
push @{$sums}, $sum;
} for @{$groups};

Fragment referenced in 9.

Defines: $sums 8.

Uses: $groups 6.

recombine 8 ⟩≡


$s = join q//, @{$sums};
return $s if length $s <= $size;
group_digit_sum($s, $size);

Fragment referenced in 9.

Uses: $size 9, $sums 7.

With that work take care of, let’s combine all these pieces into one subroutine.

group digit sum 9 ⟩≡


sub group_digit_sum{
my($s, $size) = @_;
my $c = [split //, $s];
divide the list into groups of the given size 6
compute the sums 7
recombine 8
}

Fragment referenced in 5.

Defines: $c 6, $size 6, 8.

Finally, here’s a few tests to confirm everything is working right.

main 10 ⟩≡


MAIN:{
say group_digit_sum q/111122333/, 3;
say group_digit_sum q/1222312/, 2;
say group_digit_sum q/100012121001/, 4;
}

Fragment referenced in 5.

Sample Run
$ perl perl/ch-2.pl 
359 
76 
162
    

References

The Weekly Challenge 311
Generated Code

posted at: 22:30 by: Adam Russell | path: /perl | permanent link to this entry