Peter
Peter Campbell Smith

Broken digits

Weekly challenge 275 — 24 June 2024

Week 275 - 24 Jun 2024

Task 2

Task — Replace digits

You are given an alphanumeric string, $str, where each character is either a letter or a digit. Write a script to replace each digit in the given string with the value of the previous letter plus (digit) places.

Examples


Example 1
Input: $str = 'a1c1e1'
Output: 'abcdef'
shift('a', 1) => 'b'
shift('c', 1) => 'd'
shift('e', 1) => 'f'

Example 2
Input: $str = 'a1b2c3d4'
Output: 'abbdcfdh'
shift('a', 1) => 'b'
shift('b', 2) => 'd'
shift('c', 3) => 'f'
shift('d', 4) => 'h'

Example 3
Input: $str = 'b2b'
Output: 'bdb'

Example 4
Input: $str = 'a16z'
Output: 'abgz'

Analysis

For this one I decided to forgo the concise 1- or 2-line answer in favour of something more readable. I simply loop over the characters in $str and do what the task says - output the chracater if alphabetic and output the previous character shifted that number of places along the alphabet if it's numeric.

There are a few unspecified cases:

  • First character is numeric (2abc)
  • Two consecutive numbers (ab34cd)
  • Shifted character goes beyond z (xy9)

In production code I would of course check for those, but I didn't in my submission.

Try it 

Try running the script with any input:



example: exc2l0en6

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2024-06-24
use utf8;     # Week 275 - task 2 - Replace digits
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

replace_digits('a9c9e9');
replace_digits('a1b2c3d4');
replace_digits('a2c6d1n6');

sub replace_digits {
    
    my ($j, $char, $str, $result, $prev);
    
    $str = shift;
    
    # loop over characters in $str
    for $j (0 .. length($str)) {
        $char = substr($str, $j, 1);
        
        # if it's a digit do the magic
        if ($j > 0 and $char =~ m|([0-9])|) {
            $result .= chr(ord($prev) + $char);
            
        # else don't
        } else {
            $result .= $char;
        }
        $prev = $char;
    }
    
    printf(qq[\nInput:  \@str = '%s'\n], $str);
    printf(qq[Output: '%s'\n], $result);
}

Output


Input:  @str = ('a9c9e9')
Output: 'ajclen'

Input:  @str = ('a1b2c3d4')
Output: 'abbdcfdh'

Input:  @str = ('a2c6d1n6')
Output: 'accident'