I’ve been doing the Weekly
Challenges. The
latest
involved list evaluation and string manipulation. (Note that this ends
today.)
Task 1: Third Maximum
You are given an array of integers, @ints
.
Write a script to find the third distinct maximum in the given array. If third maximum doesn’t exist then return the maximum number.
Most of the heavy lifting is done up front here: deduplicate the list,
then sort it in descending order. Then check the size, and return
the value at either index 2 or index 0.
The PostScript version seems cleanest:
/thirdmaximum {
Convert to a hash (deduplicating keys) and return the keys, then sort
and reverse.
toset keys quicksort reverse
Get the array's length, then pick an index.
dup length 2 gt {
2
} {
0
} ifelse
get
} bind def
More coventionally in Rust, which actually has an explicit dedup
(though only for adjacent elements, which is why I sort first)::
fn thirdmaximum(a: Vec<u32>) -> u32 {
let mut p = a.clone();
p.sort();
p.reverse();
p.dedup();
if p.len() > 2 {
p[2]
} else {
p[0]
}
}
Task 2: Jumbled Letters
I'll elide the descriptive text, but the key requirements:
Your task is to write a program that takes English text as its input
and outputs a jumbled version as follows:
-
The first and last letter of every word must stay the same
-
The remaining letters in the word are scrambled in a random order
(if that happens to be the original order, that is OK).
-
Whitespace, punctuation, and capitalization must stay the same
This is a job for regular expressions, so I didn't even try it in
PostScript. Raku:
sub jumble($a) {
my @p = $a.comb;
return @p.pick(@p.elems).join('');
}
for lines() {
.chomp;
my $line = $_;
$line ~~ s:g[(<[A..Za..z]>)(<[A..Za..z]><[A..Za..z]>+)(<[A..Za..z]>)] = $0 ~ jumble($1) ~ $2;
say $line;
}
In other words: for every occurrence of (letter, two or more letters,
letter), shuffle the inner group of two or more and replace the
original.
Raku's "regular expressions" use a markedly divergent syntax from real
ones, and the cpature gropus start at $0
rather than $1
as
everyone else does it. I tried putting the regex in a variable so that
it wouldn't have to be parsed each line, but this simply failed with a
cryptic error (as in Perl). In a more reasonable language like Ruby:
def jumble(a)
a.chars().shuffle.join
end
wordre = Regexp.new("([A-Za-z])([A-Za-z][A-Za-z]+)([A-Za-z])")
while line = gets
line = line.chomp
l = line.gsub(wordre) { $1 + jumble($2) + $3 }
print("#{l}\n")
end
Full code on
github.