Weekly Challenge 328
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.
Task 1: Replace all question marks
Task
You are given a string containing only lower case English letters and ?
.
Write a script to replace all ?
in the given string so that the string doesn't contain consecutive repeating characters.
My solution
For this one, I will start with the Perl solution. Strings in Perl are mutable (i.e. they can change). For this task, I loop through the position of each character with the variable idx
, and assign the char
variable to the character at that position.
sub main ($input_string) {
my $solution = $input_string;
foreach my $idx ( 0 .. length($solution) - 1 ) {
my $char = substr( $solution, $idx, 1 );
if ( $char ne '?' ) {
next;
}
If char
is not ?
, I move onto the next character. I then have an hash called %letters
. If idx
is not 0 (i.e. the first character), I add the preceding character to the letters
hash. If idx
isn't the last character's position, I add the following character to the letters
hash. The letters
hash now has the preceding and following character.
my %letters = ();
if ( $idx > 0 ) {
$letters{ substr( $solution, $idx - 1, 1 ) } = 1;
}
if ( $idx < length($solution) - 1 ) {
$letters{ substr( $solution, $idx + 1, 1 ) } = 1;
}
The last step to is replace the question mark with a letter, using the following rules.
- If
letters
does not have ana
, replace it witha
. - If
letters
does not have anb
, replace it withb
. - Replace it with
c
.
if ( not exists $letters{'a'} ) {
substr( $solution, $idx, 1 ) = 'a';
}
elsif ( not exists $letters{'b'} ) {
substr( $solution, $idx, 1 ) = 'b';
}
else {
substr( $solution, $idx, 1 ) = 'c';
}
}
say '"', $solution, '"';
}
The Python solution uses the same logic, but builds the solution
value letter by letter. In Python, strings are immutable (i.e. they cannot be changed).
def replace_all_questions(input_string: str) -> str:
solution = ''
for idx, char in enumerate(input_string):
if char != '?':
solution += char
continue
letters = []
if idx > 0:
letters.append(input_string[idx - 1])
if idx < len(input_string) - 1:
letters.append(input_string[idx + 1])
if 'a' not in letters:
solution += 'a'
elif 'b' not in letters:
solution += 'b'
else:
solution += 'c'
return solution
Examples
$ ./ch-1.py a?z
"abz"
$ ./ch-1.py pe?k
"peak"
$ ./ch-1.py gra?te
"grabte"
$ ./ch-1.py gra?be
"gracbe"
Task 2: Good String
Task
You are given a string made up of lower and upper case English letters only.
Write a script to return the good string of the given string. A string is called good string if it doesn’t have two adjacent same characters, one in upper case and other is lower case.
My solution
This is more straight forward, although GitHub Copilot got rather confused with what was expected. For this task, I start by setting the solution
variable to the same as the input string.
I then have an loop that runs continuously. Within that is an inner loop with the variable idx
which starts at zero until two less than the length of solution
. This is done as we don't want to check the last character, it has no next character.
If the letter at that place is upper case and the next letter is the same but lower case, or visa versa, I remove those two characters, and the outer loop will be called again.
If no characters are removed, the else: break
clause will exit the outer loop.
def good_string(input_string: str) -> str:
solution = input_string
while True:
for idx in range(0, len(solution)-1):
char = solution[idx]
if ((char.isupper() and solution[idx + 1] == char.lower()) or
(char.islower() and solution[idx + 1] == char.upper())):
solution = solution[:idx] + solution[idx + 2:]
break
else:
break
return solution
The Perl solution follows the same logic, but with a slightly different syntax.
Examples
$ ./ch-2.py WeEeekly
"Weekly"
$ ./ch-2.py abBAdD
""
$ ./ch-2.py abc
"abc"
Top comments (0)