Perl Weekly Challenge 255: Odd Character

These are some answers to the Week 255, Task 1, of the Perl Weekly Challenge organized by Mohammad S. Anwar.

Spoiler Alert: This weekly challenge deadline is due in a few days from now (on February 11, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.

Task 1: Odd Character

You are given two strings, $s and $t. The string $t is generated using the shuffled characters of the string $s with an additional character.

Write a script to find the additional character in the string $t.

Example 1

Input: $s = "Perl" $t = "Preel"
Output: "e"

Example 2

Input: $s = "Weekly" $t = "Weeakly"
Output: "a"

Example 3

Input: $s = "Box" $t = "Boxy"
Output: "y"

Odd Character in Raku

This task is really simple in Raku: we simply convert each input string into a Bag of its letters, and then use the (-) infix set difference operator to find the extra item in $t. So we end up with a short one-line subroutine.

sub odd-char ($s, $t) {
    return ~ ($t.comb.Bag (-) $s.comb.Bag);
}

for <Perl Preel>, <Weekly Weeakly>, <Box Boxy> -> @test {
    printf "%-8s %-8s => ", @test;
    say odd-char @test[0], @test[1];
}

This program displays the following output:

$ raku ./odd-characters.raku
Perl     Preel    => e
Weekly   Weeakly  => a
Box      Boxy     => y

Odd Character in Perl

The solution is slightly more complicated in Perl, because Perl doesn't have Bags and set difference operators. We can easily replace bags with hashes (with values being the frequency of each letter). Then we have to find the extra hash item in %t.

use strict; use warnings; use feature 'say';

sub odd_char {
    my (%s, %t);
    %s = map { $_ => ++$s{$_} } split //, $_[0];
    %t = map { $_ => ++$t{$_} } split //, $_[1];
    my @result = grep { (not defined $s{$_}) 
        or $t{$_} - $s{$_} > 0 } keys %t;
}

for my $test ([<Perl Preel>], [<Weekly Weeakly>], [<Box Boxy>]) {
    printf "%-8s %-8s => ", @$test;
    say odd_char $test->[0], $test->[1];
}

This program displays the following output:

$ perl  ./odd-characters.pl
Perl     Preel    => e
Weekly   Weeakly  => a
Box      Boxy     => y

Wrapping up

The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on February 18, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.

Leave a comment

About laurent_r

user-pic I am the author of the "Think Perl 6" book (O'Reilly, 2017) and I blog about the Perl 5 and Raku programming languages.