I’ve been doing the Weekly
Challenges. The
latest
involved array scanning and transformations. (Note that this ends today.)
Again I've had a busy few days so I only did this in seven
languages.
Task 1: Peak Positions
You are given an array of integers, @ints.
Find all the peaks in the array, a peak is an element that is
strictly greater than its left and right neighbours. Return the
indices of all such peak positions.
Raku:
sub peakpositions(@a) {
my @out;
for @a.kv -> $i, $x {
If we're at the left edge or higher than the previous value;
if (($i == 0 || $x > @a[$i - 1]) &&
AND we're at the right edge or higher than the next value:
($i == @a.end || $x > @a[$i + 1])) {
Count this as a peak.
@out.push($i);
}
}
@out;
}
Task 2: Last Visitor
You are given an integer array @ints where each element is either
a positive integer or -1.
We process the array from left to right while maintaining two lists:
@seen: stores previously seen positive integers (newest at the front)
@ans: stores the answers for each -1
Rules:
If $ints[i] is a positive number → insert it at the front of
@seen
If $ints[i] is -1:`Let $x be how many -1s in a row we've seen before
this one.
If $x > len(@seen) → append seen[x] to @ans
Else → append -1 to @ans
At the end, return @ans.
Typst:
#let lastvisitor(a) = {
Set up some working variables.
let seen = ()
let ans = ()
let minusones = 0
Iterate over the list.
for n in a {
If it's -1,
if n == -1 {
Add one to the count of -1s in a row.
minusones += 1
Then push the appropriate value on to the output list.
if minusones <= seen.len() {
ans.push(seen.at(minusones - 1))
} else {
ans.push(-1)
}
Otherwise, prepend it to the seen list.
} else {
seen.insert(0, n)
minusones = 0
}
}
ans
}
Scala: what an interesting syntax for prepending something to a
ListBuffer.
n +=: seen
Full code on
github.