#!/usr/bin/perl -s use v5.16; use Test2::V0; use Math::Prime::Util qw(permtonum numtoperm); use experimental qw(signatures postderef); our ($tests, $examples, $verbose, $rank); run_tests() if $tests || $examples; # does not return die <@{sort {$a <=> $b} @$n} = (0 .. $#$n); permtonum([@s{@$n}]); } # For the reverse operation the order of the given items is irrelevant # as rank k=0 always represents the ordered list and all other ranks are # derived from this starting point. Find the permutation # corresponding to rank k and use it as array indices in the sorted # list. sub rank2perm ($k, $n) { [(sort {$a <=> $b} @$n)[numtoperm(@$n, $k)]]; } ### Examples and tests sub run_tests { SKIP: { skip "examples" unless $examples; is perm2rank([1, 0, 2]), 2, 'example 1'; is rank2perm(1, [0, 1, 2]), [0, 2, 1], 'example 2'; } SKIP: { skip "tests" unless $tests; is perm2rank([100, 1, 10]), 4, 'perm2rank'; is rank2perm(4, [10, 100, 1]), [100, 1, 10], 'rank2perm'; } done_testing; exit; }