I’ve been doing the Weekly
Challenges. The
latest
involved REPLACEME_DESC. (Note that this ends today.)
Task 1: Word Count
You are given a list of words containing alphabetic characters only.
Write a script to return the count of words either starting with a
vowel or ending with a vowel.
In my Perl-first days I'd have used regular expressions, and in some
languages that's still the best option, but my current polyglot
mindset has helped me see the strengths of different languages. For
example in Crystal I can use nested cases:
def wordcount(a)
ct = 0
a.each do |w|
ct += case w[0]
when 'a', 'e', 'i', 'o', 'u'
1
else
case w[-1]
when 'a', 'e', 'i', 'o', 'u'
1
else
0
end
end
end
ct
end
while PostScript gets string searches:
/wordcount {
0 dict begin
[ exch
{
dup
0 1 getinterval (aeiou) exch search {
pop pop pop pop 1
} {
pop
dup length 1 sub 1 getinterval (aeiou) exch search {
pop pop pop 1
} {
pop 0
} ifelse
} ifelse
} forall
] { add } reduce
end
} bind def
and Perl sticks with regexps:
sub wordcount($a) {
my $ct = 0;
foreach my $w (@{$a}) {
if ($w =~ /^[aeiou]/ || $w =~ /[aeiou]$/) {
$ct++;
}
}
$ct;
}
Task 2: Minimum Common
You are given two arrays of integers.
Write a script to return the minimum integer common to both arrays.
If none found return -1.
I treat this as a set intersection. In Raku:
sub minimumcommon(@a, @b) {
my %aa = Set.new(@a);
my %bb = Set.new(@b);
my %cc = %aa (&) %bb;
if (%cc.elems > 0) {
%cc.keys.min;
} else {
-1;
}
}
And I'm introducing a new language to these things, at least for the
moment: Typst, which is not really designed as a
general-purpose programming language at all; it's a layout engine, in
the manner of TeX or Troff. But I've been using it for a lot of
document production recently, any sufficiently complicated document
production system is in effect a programming language even if the
designers try to hide it (which in this case they don't), and I
thought that the best way to get familiar with its programming
capabilities would be to add it to the set of languages I use here.
It doesn't have a set type, so I need a converter from array to "set"
(as in Perl, Lua, PostScript and others, a hash/dict/map with every
value locked to true
does double duty for me). Set keys here have to
be strings, but we do at least have a working map
and filter
.
#let arr2set(a) = {
a.map(x => (str(x), true)).to-dict()
}
Then the actual code is pretty much the same as the above.
#let minimumcommon(a, b) = {
let aa = arr2set(a)
let bb = arr2set(b)
let cc = aa.keys().filter(x => x in bb).map(x => int(x))
if cc.len() == 0 {
-1
} else {
calc.min(.. cc)
}
}
Full code on
github.