I’ve been doing the Weekly
Challenges. The
latest
involved string searching. (Note that this ends today.)
Task 1: Count Vowel
You are given a string.
Write a script to return all possible vowel substrings in the given
string. A vowel substring is a substring that only consists of
vowels and has all five vowels present in it.
With the slight complication that we want the shortest possible: given
a fragment "aeiouu" we return "aeiou" and not also "aeiouu". In Rust:
fn countvowel(a0: &str) -> Vec<String> {
Break the string into a list of characters.
let a = a0.chars().collect::<Vec<_>>();
Initialise the output list.
let mut found = Vec::new();
Starting length value, which we may reset later.
let mut l = a.len();
Loop from (length - 5) down to 0 for a starting position.
for start in (0..=l - 5).rev() {
Loop from 5 characters after that to the "end of the string" (see later).
'END: for eend in start + 5..=l {
Extract this substring, and make a set of its characters.
let mut sample = a[start..eend].iter().collect::<HashSet<_>>();
If any of the vowels is not present in the sample, break out of this
loop and go to the next (earlier) starting position.
for c in ['a', 'e', 'i', 'o', 'u'] {
if !sample.contains(&c) {
continue 'END;
}
sample.remove(&c);
}
Otherwise, if there weren't any other characters (i.e. a successful
match), note this substring, and then reset the "end of the string" to
one character before this substring ended. That is to say, we make
sure the last character in this substring is no longer available for
comparison. Then jump to the next (earlier) starting position.
if sample.len() == 0 {
found.push(a[start..eend].iter().collect::<String>());
l = eend - 1;
break;
}
}
}
Sort the results, for convenience of testing. (Can't use a Set as
there may be duplicates.)
found.sort();
found
}
Task 2: Largest Same-digits Number
You are given a string containing 0-9 digits only.
Write a script to return the largest number with all digits the same
in the given string.
Fortunately there's a nice deterministic way to generate all
possibilities, so I just search exhaustively. In Perl:
sub largestsamedigitsnumber($a) {
Count down from the longest possible string.
foreach my $l (reverse (1 .. length($a))) {
Within that length, count down digits. (So a three-character string
will be searched for 999, 888, 777, [...], 222, 111, 99, 88, 77.
[...])
foreach my $n (reverse (1 .. 9)) {
Build a search string.
my $test = $n x $l;
If it's in the input, return its numerical value.
if (index($a, $test) > -1) {
return 0 + $test;
}
}
}
If we didn't find anything, return zero. (In the special case of a
string with only zeroes.)
0;
}
Full code on
codeberg.