aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Sommrey <28217714+jo-37@users.noreply.github.com>2023-02-21 21:36:20 +0100
committerJörg Sommrey <28217714+jo-37@users.noreply.github.com>2023-02-26 15:47:10 +0100
commitef456ff2d17cea9d4ba1a4ea5a3a2ff202669be2 (patch)
tree1e17c513f620a22821622183f92a0a3172a7baf9
parent20cf23de63b452a5cee63c7b10d842afbf09cfb2 (diff)
downloadperlweeklychallenge-club-ef456ff2d17cea9d4ba1a4ea5a3a2ff202669be2.tar.gz
perlweeklychallenge-club-ef456ff2d17cea9d4ba1a4ea5a3a2ff202669be2.tar.bz2
perlweeklychallenge-club-ef456ff2d17cea9d4ba1a4ea5a3a2ff202669be2.zip
Solution to task 1
-rwxr-xr-xchallenge-205/jo-37/perl/ch-1.pl81
1 files changed, 81 insertions, 0 deletions
diff --git a/challenge-205/jo-37/perl/ch-1.pl b/challenge-205/jo-37/perl/ch-1.pl
new file mode 100755
index 0000000000..9df8da3d12
--- /dev/null
+++ b/challenge-205/jo-37/perl/ch-1.pl
@@ -0,0 +1,81 @@
+#!/usr/bin/perl -s
+
+use v5.16;
+use Test2::V0 '!float';
+use PDL;
+use PDL::NiceSlice;
+use List::Util 'uniqnum';
+
+our ($tests, $examples, $n);
+
+$n //= 3;
+
+run_tests() if $tests || $examples; # does not return
+
+die <<EOS unless @ARGV;
+usage: $0 [-examples] [-tests] [--] [N...]
+
+-examples
+ run the examples from the challenge
+
+-tests
+ run some tests
+
+-n=N
+ find N-th largest element. Default: 3
+
+N...
+ list of integers
+
+EOS
+
+
+### Input and Output
+
+say nth_max($n, @ARGV);
+
+
+### Implementation
+
+# Keep N in the "N-th" largest element variable.
+
+sub nth_max {
+ my $n = shift;
+ # Not using PDL's "uniq" because it would sort the data. There's a
+ # significant difference in running time for larger lists.
+ my $l = pdl uniqnum @_;
+
+ # The "otherwise" branch: there is no n-th maximal element.
+ return max $l if $l->nelem < $n;
+
+ # Find the indices of the n largest elements. Populates the second
+ # argument in its given size.
+ maximum_n_ind $l, my $max_ind = zeroes indx, $n;
+
+ # Pick the element indexed by the last in list, which is the n-th
+ # largest.
+ $l($max_ind(-1))->sclr;
+}
+
+
+### Examples and tests
+
+sub run_tests {
+ SKIP: {
+ skip "examples" unless $examples;
+
+ is nth_max(3, (5, 3, 4)), 3, 'example 1';
+ is nth_max(3, (5, 6)), 6, 'example 2';
+ is nth_max(3, (5, 4, 4, 3)), 3, 'example 3';
+ }
+
+ SKIP: {
+ skip "tests" unless $tests;
+
+ is nth_max(3, (3, 4, 3, 4, 3)), 4, 'not enought unique numbers';
+ }
+
+
+ done_testing;
+ exit;
+}