DEV Community

Simon Green
Simon Green

Posted on

Broken letters

Weekly Challenge 313

Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.

Challenge, My solutions

Task 1: Broken Keys

Task

You have a broken keyboard which sometimes type a character more than once.

You are given a string and actual typed string.

Write a script to find out if the actual typed string is meant for the given string.

My solution

This is a two liner for both the Perl and Python solutions. I can use a regular expression to see if the typed value contains one or more of each character in the name variable.

The thing that needs to be handled is escaping any characters that have special meaning in a regular expression. Thankfully Perl has quotemeta and Python has re.escape method to handle this.

The entire regular expressions starts with ^ to signify the start of the string. It then has each letter (escaped if required) followed by a + character, which means one or more of that letter. The regular expression ends with a $ for the end of the string.

Python

def broken_keys(name: str, typed: str) -> bool:
    r = '^' + '+'.join(map(re.escape, name)) + '+$'
    return re.search(r, typed)
Enter fullscreen mode Exit fullscreen mode

Perl

sub main ( $name, $typed ) {
    my $r = '^' . join( '+', map { quotemeta } split //, $name ) . '+$';
    say $typed =~ $r ? 'true' : 'false';
}
Enter fullscreen mode Exit fullscreen mode

Examples

$ ./ch-1.py perl perrrl
True

$ ./ch-1.py raku rrakuuuu
True

$ ./ch-1.py python perl
False

$ ./ch-1.py coffeescript cofffeescccript
True
Enter fullscreen mode Exit fullscreen mode

Task 2: Reverse Letters

Task

You are given a string.

Write a script to reverse only the alphabetic characters in the string.

My solution

Let's start with discussion about my Perl solution. This also is a two liner. The first line extracts all the letters from the string, and stores it in the array called @letters. The second line replaces all the letters by calling pop(@letters) each time a letter is found.

The regular expression has three modifiers:

  • i is for a case insensitive search
  • g is for global (replace all occurrences)
  • e will evaluate the right side as an expression.
sub main ($str) {
    my @letters    = grep { /[a-z]/i } split //, $str;
    $str =~ s/[a-z]/pop(@letters)/ige;
    say $str;
}
Enter fullscreen mode Exit fullscreen mode

I was thinking that my Python solution would be use the same logic. But it turns out that letters.pop() is only computed once, and thus all the letters are replaced with the last letter found.

I'm not entirely sure the reasons why, and given that this isn't my day job, I'm not going to spend too much time on finding out why :)

My Python solution starts out the same by extracting all the letters found into list called letters.

def reversed_letters(typed: str) -> str:
    letters = [s for s in typed if s.isalpha()]
Enter fullscreen mode Exit fullscreen mode

I then go though each character in the original string. If it is a letter, I take the last letter from the letters list and add it to the new_string variable. If it isn't, I add the character to the new_string variable.

    new_string = ''
    for char in typed:
        if char.isalpha():
            new_string += letters.pop()
        else:
            new_string += char

    return new_string
Enter fullscreen mode Exit fullscreen mode

One thing to note is the Perl solution will only match the 26 letters of the English alphabet. The Python solution will match characters of any alphabet.

Examples

The second and third examples are surrounded in quotes as the exclamation mark (!) has special meaning in bash.

$ ./ch-2.py p-er?l
l-re?p

$ ./ch-2.py 'wee-k!L-y'
yLk-e!e-w

$ ./ch-2.py '_c-!h_all-en!g_e'
_e-!g_nel-la!h_c
Enter fullscreen mode Exit fullscreen mode

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

Image of Timescale

📊 Benchmarking Databases for Real-Time Analytics Applications

Benchmarking Timescale, Clickhouse, Postgres, MySQL, MongoDB, and DuckDB for real-time analytics. Introducing RTABench 🚀

Read full post →

👋 Kindness is contagious

If you found this post useful, please drop a ❤️ or a friendly comment!

Okay.