Peter’s blog ✴ Week 313 ✴ 17 March 2025

THE WEEKLY CHALLENGE
Broken letters

The Perl Camel

Task 2

Reverse letters

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

Examples


Example 1
Input: $str = "p-er?l"
Output: "l-re?p"

Example 2
Input: $str = "wee-k!L-y"
Output: "yLk-e!e-w"

Example 3
Input: $str = "_c-!h_all-en!g_e"
Output: "_e-!g_nel-la!h_c"

Analysis

Someone will no doubt come up with a one-liner, but my solution:

  • Extracts the letters from the string as another string
  • Reverses that string
  • Builds the output string by substiting the next letter from the reversed string for each letter in the original string.

Perl Weekly’s review

from Perl Weekly issue 713

With regex based solution, I always need explanation otherwise you spend good amount of time to get your head around if it is a complex one. Here you even have DIY tool to test it as well. Great work.

Try it 

Try running the script with any input:



example: gnos-a-gnis

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2025-03-17
use utf8;     # Week 313 - task 2 - Reverse letters
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

reverse_letters('p-er?l');
reverse_letters('wee-k!L-y');
reverse_letters('_c-!h_all-en!g_e');
reverse_letters('neerg:si:ssarg');

sub reverse_letters {
    
    my ($string, $letters, $reversed, $char, $i);
    
    # extract letters and reverse them
    $string = shift;
    $letters = $string;
    $letters =~ s|[^a-z]||gi;
    $letters = reverse($letters);
    
    # substitute a reversed letter for every letter in string
    for $char (split('', $string)) {
        $reversed .= $char =~ m|[a-z]|i ? substr($letters, $i ++, 1) : $char;
    }
    
    # report
    say qq[\nInput:  \$string   = '$string'];
    say qq[Output: \$reversed = '$reversed'];
}

10 lines of code

Output from script


Input:  $string   = 'p-er?l'
Output: $reversed = 'l-re?p'

Input:  $string   = 'wee-k!L-y'
Output: $reversed = 'yLk-e!e-w'

Input:  $string   = '_c-!h_all-en!g_e'
Output: $reversed = '_e-!g_nel-la!h_c'

Input:  $string   = 'neerg:si:ssarg'
Output: $reversed = 'grass:is:green'

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain