I’ve been doing the Weekly
Challenges. The
latest
involved string replacements. (Note that this ends today.)
Since I'm still away I only did this one in Rust again.
Task 1: Replace all ?
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.
In order to conform to the examples given, I used the earliest valid
replacement character.
fn replaceall(a: &str) -> String {
Split the string into a vector of characters.
let mut ci = a.chars().collect::<Vec<char>>();
let l = a.len() - 1;
Iterate over each character.
for i in 0..=l {
let c = ci[i];
If it's a "?",
if c == '?' {
try "a" as a replacement character,
let mut r = 'a';
and each time it's the same as a neighbour,
while (i > 0 && ci[i - 1] == r) || (i < l && ci[i + 1] == r) {
increment it..
r = std::char::from_u32(r as u32 + 1).unwrap();
}
Then drop that in so that if the next character is a "?" its
replacement needs not to match the one we've just found.
ci[i] = r;
}
}
Assemble the characters back into a string.
ci.into_iter().collect()
}
Task 2: Good String
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.
fn goodstring(a: &str) -> String {
Again, split the string to characters.
let mut c = a.chars().collect::<Vec<char>>();
We haven't verified that the string is as stripped down as it can be.
let mut dirty;
loop {
dirty = false;
Look through the list of characters by adjacent pairs.
for i in 0..c.len() - 1 {
If this character is not the same case as the next,
if (c[i].is_ascii_lowercase() && c[i + 1].is_ascii_uppercase())
|| (c[i].is_ascii_uppercase() && c[i + 1].is_ascii_lowercase())
{
See if they're the same character if they're both in lower case.
let mut ca = c[i];
let mut cb = c[i + 1];
ca.make_ascii_lowercase();
cb.make_ascii_lowercase();
if ca == cb {
If that's the case, splice the string. In that case, we'll start again
from the beginning, in case a new pair has been formed by the deletion
(see example 2).
dirty = true;
c.splice(i..=i + 1, []);
break;
}
}
}
If we didn't change anything, or there's no string left (example 2
again), drop out and return what we have.
if !dirty || c.len() == 0 {
break;
}
}
c.into_iter().collect()
}
Full code on
github.