Camel
Peter
Peter Campbell Smith

Questions are good

Weekly challenge 328 — 30 June 2025

Week 328: 30 Jun 2025

Task 1

Task — Replace all ?

You are given a string containing only lower case English letters and '?'s. Write a script to replace every '?' in the given string so that the string doesn’t contain consecutive repeating characters.

Examples


Example 1
Input: $str = 'a?z'
Output: 'abz'
There can be many strings, one of them is 'abz'.
The choices are 'a' to 'z' but we can't use either 'a' or 
   'z' to replace the '?'.

Example 2
Input: $str = 'pe?k'
Output: 'peak'

Example 3
Input: $str = 'gra?te'
Output: 'grabte'

Analysis

Let's look for all the '?' characters, noting what character comes immediately before and after them - call those $a and $b. To avoid creating a doubled letter we have to substitute a new letter in place of the '?', and in every case we can use 'a', 'b' or 'c'. Specifically, we can use 'a' if neither of the surrounding letters is 'a', or use 'b' if neither is 'b', or in the cases where one is 'a' and the other is 'b' we can insert 'c'.

To do that with a regular expression we have a slight problem if the string starts or ends with a '?', and to get round that I added a non-letter ('*') to the start and end of the string before searching it for '?'s and then stripped them off the resulting string.

Note that the challenge is silent as to what happens if the input string already contains doubled letter, such as 'abbc?d', and my algorithm will leave them unchanged.

Try it 

Try running the script with any input:



example: s?l?m?nder

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2025-06-30
use utf8;     # Week 328 - task 1 - Replace all ?
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

replace_all_queries('abc?def?ghi');
replace_all_queries('?a?a?a?a?a?a?a?');
replace_all_queries('a?????b');
replace_all_queries('?????');
replace_all_queries('?br?c?d?br?');
replace_all_queries('a??????b');
replace_all_queries('a?b?a?b?c?a');

sub replace_all_queries {
    
    my ($string, $z);
    
    # initialise - add '*' to start and end
    $string = qq[*$_[0]*];
    
    # loop while string contains a '?'
    while ($string =~ m|^(.*?)(.)\?(.?)(.*)|) {
        
        # replace ? with a, b or c
        for $z ('a', 'b', 'c') {
            if ($z ne $2 and $z ne $3) {
                $string = qq[$1$2$z$3$4];
                last;
            }
        }
    }   
    
    say qq[\nInput:  $_[0]];
    say qq[Output: ] . substr($string, 1, -1);
}

Output


Input:  abc?def?ghi
Output: abcadefaghi

Input:  ?a?a?a?a?a?a?a?
Output: bababababababab

Input:  a?????b
Output: ababacb

Input:  ?????
Output: ababa

Input:  ?br?c?d?br?
Output: abracadabra

Input:  a??????b
Output: abababab

Input:  a?b?a?b?c?a
Output: acbcacbacba

 

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