DEV Community

vinodk89
vinodk89

Posted on

Perl Weekly Challenge - 358: When Strings Become Numbers and Letters Start Shifting

One of the things I enjoy about the Weekly Perl Challenge (WPC) is how small problems often hide neat programming ideas.
This week, I solved two challenges that look simple at first glance but beautifully showcase Perl’s strengths in:

  • String handling
  • Regex usage
  • Numeric/string duality
  • ASCII manipulation
  • Writing clean, testable code

Let’s walk through both problems and the approach I used.


Challenge 1 — When Strings Become Numbers

Problem
You are given a list of strings. For each string:

  • If it contains only digits, treat it as a number
  • Otherwise, treat its length as its value From these values, return the maximum.

Example

Strings Interpreted as Maximum
"123", "45", "6" 123, 45, 6 123
"abc", "de", "fghi" 3, 2, 4 4
"0012", "99", "a1b2c" 12, 99, 5 99

Key Observation
The heart of the problem is deciding:

“Is this string purely numeric, or not?”
Perl makes this very easy with a simple regex.


Solution

use List::Util qw(max);

sub get_value {
    my $str = shift;

    return length($str) unless $str =~ /^\d+$/;
    return 0 + $str;
}
Enter fullscreen mode Exit fullscreen mode

A tiny function does all the work:

  • ^\d+$ → checks if the string is fully numeric
  • length($str) → used when it’s not
  • 0 + $str → converts "0012" into number 12 Then finding the maximum is trivial with map and max:
my $max = max(map { get_value($_) } @strings);
Enter fullscreen mode Exit fullscreen mode

This is where Perl shines — very little code, very clear intent.


Challenge 2 — Caesar Cipher (Letter Shifting)

Problem
Implement a Caesar Cipher:

  • Shift every lowercase letter by N
  • Wrap around from z to a
  • Leave other characters unchanged
Input Shift Output
"abc" 1 "bcd"
"xyz" 2 "zab"
"hello" 5 "mjqqt"
"perl" 26 "perl"

Key Observation
This problem is a perfect use case for ASCII arithmetic.
Instead of thinking in terms of alphabets, think in numbers from 0 to 25.


sub caesar_encrypt {
    my ($str, $int) = @_;
    $int %= 26;

    my $result = '';
    for my $char (split //, $str) {
        if ($char =~ /[a-z]/) {
            $result .= chr(
                (ord($char) - ord('a') + $int) % 26 + ord('a')
            );
        } else {
            $result .= $char;
        }
    }
    return $result;
}
Enter fullscreen mode Exit fullscreen mode

This one line does the magic:

chr((ord($char) - ord('a') + $int) % 26 + ord('a'))
Enter fullscreen mode Exit fullscreen mode

Steps:

  1. Convert letter → ASCII (ord)
  2. Normalize to 0–25 range
  3. Add the shift
  4. Use modulo to wrap around
  5. Convert back to character (chr)
  6. No lookup tables. No special cases. Just math.

Testing the Solutions
For both challenges, I wrote small test cases and printed PASS/FAIL results.
This is a habit I’ve picked up from solving WPC regularly — even small scripts deserve tests.


Why I Loved These Challenges
These problems highlight why Perl is still a joy for problem solving:

  • Regex makes validation trivial
  • Numeric and string contexts work naturally
  • Character manipulation is straightforward
  • Functional tools like map make code concise
  • Very expressive in very few lines

Final Thoughts
At first glance, these look like beginner problems.
But they actually touch on important concepts:

  • Data interpretation
  • Input validation
  • ASCII math
  • Writing minimal, readable logic And Perl handles all of this elegantly.

That’s what makes the Weekly Perl Challenge so enjoyable — small puzzles, big learning.

Top comments (0)