perl logo Perl logo (Thanks to Olaf Alders)

The weekly challenge 313 - Task 2: Reverse Letters

 1 #!/usr/bin/env perl
 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-313/#TASK2
 3 #
 4 # Task 2: Reverse Letters
 5 # =======================
 6 #
 7 # You are given a string.
 8 #
 9 # Write a script to reverse only the alphabetic characters in the string.
10 #
11 ## Example 1
12 ##
13 ## Input: $str = "p-er?l"
14 ## Output: "l-re?p"
15 #
16 ## Example 2
17 ##
18 ## Input: $str = "wee-k!L-y"
19 ## Output: "yLk-e!e-w"
20 #
21 ## Example 3
22 ##
23 ## Input: $str = "_c-!h_all-en!g_e"
24 ## Output: "_e-!g_nel-la!h_c"
25 #
26 ############################################################
27 ##
28 ## discussion
29 ##
30 ############################################################
31 #
32 # For each alphabetic character, we take note of the index
33 # inside the original string and the character itself. However,
34 # we do this in a way that we have the indices in reversed order.
35 # Now we can walk both lists in parallel, substituting the
36 # character at the position of the index for the character in the
37 # list. Since the indices are reversed, we have everything in the
38 # order we want in the end.
39 
40 use v5.36;
41 
42 reverse_letters( "p-er?l" );
43 reverse_letters( "wee-k!L-y" );
44 reverse_letters( "_c-!h_all-en!g_e" );
45 
46 sub reverse_letters($str) {
47    say "Input: \"$str\"";
48    my @str = split //, $str;
49    my @indices = ();
50    my @tmp = ();
51    foreach my $i (0..$#str) {
52       if($str[$i] =~ m/[a-zA-Z]/) {
53          unshift @indices, $i;
54          push @tmp, $str[$i];
55       }
56    }
57    foreach my $i (0..$#indices) {
58       $str[$indices[$i]] = $tmp[$i];
59    }
60    say "Output: " . join("", @str);
61 }