I’ve been doing the Weekly
Challenges. The
latest
involved filtering strings and lists. (Note that this is open until 4
September 2022.)
Task 1: First Unique Character
You are given a string, $s
.
Write a script to find out the first unique character in the given
string and print its index (0-based).
My approach here is to iterate twice: the first pass builds up a
character count and the second looks for the first character with a
count of 1. (Another approach would involve a linked list to let a
first-unique-character counter fall through the string as counts got
too high, but I think this is clearer.)
Raku is typical:
sub firstunique($s) {
Split the string to individual characters.
my @s = $s.comb;
Built a hash mapping character to count.
my %cc;
map {%cc{$_}++}, @s;
Go through the string character by character, until we find one with a
count of 1.
for 0..@s.end -> $i {
if (%cc{@s[$i]} == 1) {
return $i;
}
}
If we didn't, return -1 (this is outside the spec but clearly possible
if there are no unique characters).
return -1;
}
Many of the languages have an "enumerate" style function that lets one
get both array member and index in a single looping construct; most
don't autovivify default hash entries, though several have some way of
specifying that for this hash the default value is that.
Task 2: Trim List
You are given list of numbers, @n
and an integer $i
.
Write a script to trim the given list where element is less than or
equal to the given integer.
This sort of thing is a core function in everything except Lua and
PostScript (and I wrote it for PostScript): in Perl and Raku it's
grep
, in Ruby it's find_all
, and everywhere else it's filter
. So
the Ruby:
def trimlist(n, i)
return n.find_all {|x| x > i}
end
is functionally the same as the JavaScript,
function trimlist(n, i) {
return n.filter(e => e > i);
}
the same as the Perl,
sub trimlist($n, $i) {
return [grep {$_ > $i} @{$n}];
}
and the same as the Rust (with a bit more complication).
fn trimlist(n: Vec<i64>, i: i64) -> Vec<i64> {
n.into_iter().filter(|&x| x > i).collect::<Vec<i64>>()
}
(Rust also has retain
which modifies a vector in place.)
Full code on
github.
Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one.