aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-111/jo-37/perl/ch-2.pl48
1 files changed, 48 insertions, 0 deletions
diff --git a/challenge-111/jo-37/perl/ch-2.pl b/challenge-111/jo-37/perl/ch-2.pl
new file mode 100755
index 0000000000..c514bdcf27
--- /dev/null
+++ b/challenge-111/jo-37/perl/ch-2.pl
@@ -0,0 +1,48 @@
+#!/usr/bin/perl -s
+
+use v5.16;
+use warnings;
+use experimental 'postderef';
+
+# The task states "find the longest English words". This could be meant
+# as "all words having the maximum length". My local dictionary has
+# only one longest word of this kind, which does not qualify as "longest
+# words" - a plural.
+# Therefore I'll interpret the term "the longest words" in a way that
+# multiple words may be found.
+#
+# Here $n defines "the longest words". In addition to the word(s)
+# having the maximum length, all lengths down to max_len - $n are
+# considered as "long", resulting in a larger set of "longest words" if
+# $n > 0.
+our $n;
+$n //= 1;
+
+die <<EOS unless @ARGV;
+usage: $0 [-n=<n>] dict...
+
+-n=<n>
+ Specify the maximum length difference from the maximum length for
+ words to be printed. Default: 1. Use -n=0 to print the maximum
+ length word(s) only.
+
+dict...
+ dictionary file name(s), e.g. /usr/share/dict/words
+
+EOS
+
+
+my @word;
+
+while (<>) {
+ chomp;
+ $_ = lc;
+ # Detect a "self-sorted" word and add it to an array of words having
+ # the same length.
+ push $word[length]->@*, $_ if join('', sort split //) eq $_;
+}
+
+# Reverse the order of the collected arrays, pick the first
+# $n + 1 thereof, dereference these and print the words.
+# @word may contain gaps.
+say for map {$_ ? @$_ : ()} (reverse @word)[0 .. $n];