Perl Weekly Challenge 282: Changing Key

These are some answers to the Week 282, Task 2, 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 August 18, 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 2: Changing Keys

You are given an alphabetic string, $str, as typed by user.

Write a script to find the number of times user had to change the key to type the given string. Changing key is defined as using a key different from the last used key. The shift and caps lock keys won’t be counted.

Example 1

Input: $str = 'pPeERrLl'
Ouput: 3

p -> P : 0 key change
P -> e : 1 key change
e -> E : 0 key change
E -> R : 1 key change
R -> r : 0 key change
r -> L : 1 key change
L -> l : 0 key change

Example 2

Input: $str = 'rRr'
Ouput: 0

Example 3

Changing Key in Raku

We could probably use a regex to design a more concise solution, but I preferred the simplicity of a single loop through the input string's letters. We set the input string to lower case before splitting into individual characters. The only small gotcha is that, according to the examples, the first pressed key is not considered as a key change. So I decided to shift the first letter of the @letters array and use it to initialize the $old variable containing the previous key within the loop.

sub changing-key ($in) {
    my $count = 0;
    my @letters = $in.lc.comb;
    my $old = shift @letters;
    for @letters -> $let {
        $old = $let and $count++ if $let ne $old;
    }
    return $count;
}

my @tests = 'pPeERrLl', 'rRr', 'GoO';
for @tests -> $test {
    printf "%-10s => ", $test;
    say changing-key $test;
}

Note BTW that the person who typed in the input examples is apparently even more dyslexic than I am.

This program displays the following output:

$ raku ./changing-key.raku
pPeERrLl   => 3
rRr        => 0
GoO        => 1

Changing Key in Perl

This is a port to Perl of the previous Raku program. Please refer to the explanations above if needed.

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

sub changing_key {
    my $count = 0;
    my @letters = split //, lc shift;
    my $old = shift @letters;
    for my $let (@letters) {
        $old = $let and $count++ if $let ne $old;
    }
    return $count;
}

my @tests = ('pPeERrLl', 'rRr', 'GoO');
for my $test (@tests) {
    printf "%-10s => ", $test;
    say changing_key $test;
}

This program displays the following output:

$ perl  ./changing-key.pl
pPeERrLl   => 3
rRr        => 0
GoO        => 1

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 August 25, 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.