I’ve been doing the Weekly
Challenges. The
latest
involved formatting strings and ranking arrays. (Note that this ends
today.)
Task 1: String Format
You are given a string and a positive integer.
Write a script to format the string, removing any dashes, in groups
of size given by the integer. The first group can be smaller than
the integer but should have at least one character. Groups should be
separated by dashes.
Many languages have a way of taking chunks of several items from an
array, but they always start at the beginning rather than allowing for
an offset — so one would have to reverse the input, process it, then
reverse it again. So I didn't do that. Raku:
sub formatstring($a, $n) {
Get a list of characters, without the dashes.
my @p = $a.comb.grep({$_ ne '-'});
The position of the first dash will be the length of the list, modulo
the format size. (E.g. "abcdef" formatted in 4 would put its first
dash at position 2, just before "c".) This may produce a spurious dash
at zero, so jump forward if that's the case.
my $r = @p.elems % $n;
if ($r == 0) {
$r += $n;
}
my $o;
Run through the character list.
for @p.kv -> $i, $c {
If we're at a dash point, add a dash and set the next dash point.
if ($r == $i) {
$o ~= '-';
$r += $n;
}
Append the character.
$o ~= $c;
}
Return the result.
$o;
}
Task 2: Rank Array
You are given an array of integers.
Write a script to return an array of the ranks of each element: the
lowest value has rank 1, next lowest rank 2, etc. If two elements
are the same then they share the same rank.
There's an obvious O(n²) solution, but hashes/maps/dicts should give
slightly better efficiency. Python:
def rankarray(a):
Get a list of entries, removing duplicates.
b = list(set(a))
Sort them.
b.sort()
Set up a new hash.
c = dict()
Use each entry as a key, and the rank as its value.
for i, n in enumerate(b):
c[n] = i + 1
Initialise the output array.
out = []
For each entry in the original, look up and insert its rank.
for v in a:
out.append(c[v])
return out
Full code on
github.