From 32a01e6bfd9c03d46b83c766c47105a94b35f027 Mon Sep 17 00:00:00 2001 From: Mike Lynch Date: Wed, 26 Jul 2023 17:57:43 +1000 Subject: [PATCH] permutation maths --- permute.js | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 permute.js diff --git a/permute.js b/permute.js new file mode 100644 index 0000000..4c99462 --- /dev/null +++ b/permute.js @@ -0,0 +1,67 @@ + +// Utilities for generating sets of coordinates based on +// permutations, even permutations and changes of sign. +// Based on https://www.qfbox.info/epermute + + +function pandita(a) { + const n = a.length; + for( let k = n - 2; k >= 0; k-- ) { + if( a[k] < a[k + 1] ) { + for( let l = n - 1; l >= 0; l-- ) { + if( a[k] < a[l] ) { + const tmp = a[k]; + a[k] = a[l]; + a[l] = tmp; + const revtail = a.slice(k + 1); + revtail.reverse(); + for( let i = 0; i < revtail.length; i++ ) { + a[k + 1 + i] = revtail[i]; + } + return Math.floor(revtail.length / 2) + 1; + } + } + console.log("Shouldn't get here"); + process.exit(); + } + } + return false; +} + +function permutations(a) { + a.sort(); + const ps = [ [...a] ]; + while( pandita(a) ) { + ps.push([...a]); + } + return ps; +} + +function permutations_even(a) { + a.sort(); + let parity = 'even'; + const ps = [ [...a] ]; + let running = true; + while( running ) { + const s = pandita(a); + if( s ) { + if( parity === 'even' ) { + if( s % 2 === 1 ) { + parity = 'odd'; + } + } else { + if( s % 2 === 1 ) { + parity = 'even'; + } + } + if( parity === 'even' ) { + ps.push([...a]); + } + } else { + running = false; + } + } + return ps; +} + +