How to resolve the algorithm Permutations/Rank of a permutation step by step in the jq programming language

Published on 12 May 2024 09:40 PM
#Jq

How to resolve the algorithm Permutations/Rank of a permutation step by step in the jq programming language

Table of Contents

Problem Statement

A particular ranking of a permutation associates an integer with a particular ordering of all the permutations of a set of distinct items. For our purposes the ranking will assign integers

0.. ( n ! − 1 )

{\displaystyle 0..(n!-1)}

to an ordering of all the permutations of the integers

0.. ( n − 1 )

{\displaystyle 0..(n-1)}

. For example, the permutations of the digits zero to 3 arranged lexicographically have the following rank: Algorithms exist that can generate a rank from a permutation for some particular ordering of permutations, and that can generate the same rank from the given individual permutation (i.e. given a rank of 17 produce (2, 3, 1, 0) in the example above). One use of such algorithms could be in generating a small, random, sample of permutations of

n

{\displaystyle n}

items without duplicates when the total number of permutations is large. Remember that the total number of permutations of

n

{\displaystyle n}

items is given by

n !

{\displaystyle n!}

which grows large very quickly: A 32 bit integer can only hold

12 !

{\displaystyle 12!}

, a 64 bit integer only

20 !

{\displaystyle 20!}

. It becomes difficult to take the straight-forward approach of generating all permutations then taking a random sample of them. A question on the Stack Overflow site asked how to generate one million random and indivudual permutations of 144 items.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Permutations/Rank of a permutation step by step in the jq programming language

Source code in the jq programming language

# Assuming sufficiently-precise integer arithmetic,
# if the input and $j are integers, then the result will be a pair of integers,
# except that if $j is 0, then an error condition is raised.
def divmod($j):
  . as $i
  | ($i % $j) as $mod
  | [($i - $mod) / $j, $mod] ;

# Input may be an object or an array
def swap($i; $j):
  .[$i] as $t
  | .[$i] = .[$j]
  | .[$j] = $t;

def factorial:
  . as $n
  | reduce range(2; $n) as $i ($n; . * $i);

def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;

# Myrvold and Ruskey algorithm
# The input should be a permutation of 0 ... $n-1 inclusive
def mrUnrank1($rank; $n):
  if $n < 1 then .
  else ($rank|divmod($n)) as [$q, $r]
  | swap($r; $n - 1)
  | mrUnrank1($q; $n - 1)
  end ;

# The input should be a permutation of 0 ... $n-1 inclusive
def mrRank1($n; $vec):
  if $n < 2 then 0
  else
  . as $inv
  | $vec
  | .[$n-1] as $s
  | swap($n - 1; $inv[$n-1]) as $vec
  | $inv
  | swap($s; $n - 1)
  | $s + $n * mrRank1($n - 1; $vec)
  end;

 
def getPermutation($rank; $n):
 [range(0; $n)]
 | mrUnrank1($rank; $n) ;

def getRank($n; $vec):
  reduce range(0; $n) as $i ( null;
    .[$vec[$i]] = $i )
  | mrRank1($n; $vec);

def task($k):
  "\($k)!",
  (range(0; $k|factorial) as $r
   | getPermutation($r; $k)
   | [ ($r|lpad(2)), tostring, (getRank($k; .) | lpad(2)) ]
   | join(" -> ") );

def task3:
  def randoms: 43154690, 150112966, 15732396, 157551691;
  "\("#"|lpad(10)) -> \("permutation"|lpad(27)) -> \("rank"|lpad(10))",
  (randoms as $r
   | getPermutation($r; 12)
   | "\($r|lpad(10)) -> \(lpad(27)) -> \(getRank(12;.)|lpad(10))" );


task(3),
"",
task(4),
"",
task3

  

You may also check:How to resolve the algorithm Character codes step by step in the DWScript programming language
You may also check:How to resolve the algorithm Averages/Arithmetic mean step by step in the EMal programming language
You may also check:How to resolve the algorithm Conditional structures step by step in the langur programming language
You may also check:How to resolve the algorithm String length step by step in the LFE programming language
You may also check:How to resolve the algorithm Hash join step by step in the M2000 Interpreter programming language