I’ve been doing the Weekly
Challenges. The
latest
involved string manipulation. (Note that this ends today.)
Task 1: Clear Digits
You are given a string containing only lower case English letters
and digits.
Write a script to remove all digits by removing the first digit and
the closest non-digit character to its left.
It seems to me that the easiest approach to this is a stack.
Crystal:
def cleardigits(a)
Set up the output stack.
out = Array(Char).new
Iterate over the characters of the input string.
a.chars.each do |c|
If this one is a digit, pop the previous character from the stack.
if c >= '0' && c <= '9'
out.pop
Otherwise, add this character to the stack.
else
out.push(c)
end
end
Join the stack into a string for output.
out.join("")
end
I was particularly happy with the PostScript implementation.
/cleardigits {
0 dict begin
Push a "start array" marker onto the system stack, below the input.
[ exch
Iterate over the input.
{
Duplicate the character, and consume one of the copies in checking
whether it's a digit. If so, dump the original and the top item on the
stack. Otherwise… it's sitting there being added automatically to the
stack, so we don't need to do anything.
dup c.isdigit {
pop pop
} if
} forall
End the array, and join into a string for output.
] a2s
end
} bind def
Task 2: Title Capital
You are given a string made up of one or more words separated by a
single space.
Write a script to capitalise the given title. If the word length is
1 or 2 then convert the word to lowercase otherwise make the first
character uppercase and remaining lowercase.
Some languages have a function to capitalise the first letter of a
string, as Perl:
sub titlecapital($a) {
Initialise the output list.
my @out;
Iterate over words.
foreach my $w (split ' ', $a) {
Always put them into lower case.
my $p = lc($w);
If they're longer than 2 characters, put the first character in upper
case.
if (length($p) > 2) {
$p = ucfirst($p);
}
Store that in the output list.
push @out, $p;
}
join(' ', @out);
}
But other languages don't necessarily have this (or I didn't find it),
so e.g. in Rust I break the string into an array of characters,
upper-case the first one, and re-join them.
fn titlecapital(a: &str) -> String {
let mut out = Vec::new();
for w in a.split(' ') {
let mut p = w.to_ascii_lowercase();
if p.len() > 2 {
let mut c = p.chars().collect::<Vec<char>>();
c[0].make_ascii_uppercase();
p = c.into_iter().collect();
}
out.push(p);
}
out.join(" ")
}
Full code on
github.