Skip to content

Commit

Permalink
v.0.9.1
Browse files Browse the repository at this point in the history
* new fuse method "combineWith", new fuse method "joinWith" (same as previous "combineWith")
* now with new fure method k-derangements can be produced by combining combinations with rest derangements
* some optimisations for magic squares and latin squares
* update tests
  • Loading branch information
foo123 committed May 18, 2019
1 parent 8ac94e9 commit 869b7cd
Show file tree
Hide file tree
Showing 31 changed files with 2,158 additions and 2,053 deletions.
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,21 @@ A combinatorics library for Node.js / Browser / XPCOM Javascript, PHP, Python, C

**see also:**

* [Contemplate](https://github.com/foo123/Contemplate) a fast and light-weight Template Engine for Node/XPCOM/JS, PHP, Python
* [HtmlWidget](https://github.com/foo123/HtmlWidget) html widgets used as (template) plugins and/or standalone for PHP, Node/XPCOM/JS, Python both client and server-side
* [Contemplate](https://github.com/foo123/Contemplate) a fast and light-weight object-oriented Template Engine for Node.js / Browser / XPCOM Javascript, PHP, Python
* [HtmlWidget](https://github.com/foo123/HtmlWidget) html widgets used as (template) plugins and/or standalone for Node.js / Browser / XPCOM Javascript, PHP, Python both client and server-side
* [Tao](https://github.com/foo123/Tao.js) A simple, tiny, isomorphic, precise and fast template engine for handling both string and live dom based templates
* [ModelView](https://github.com/foo123/modelview.js) a light-weight and flexible MVVM framework for JavaScript/HTML5
* [ModelView MVC jQueryUI Widgets](https://github.com/foo123/modelview-widgets) plug-n-play, state-full, full-MVC widgets for jQueryUI using modelview.js (e.g calendars, datepickers, colorpickers, tables/grids, etc..) (in progress)
* [Importer](https://github.com/foo123/Importer) simple class & dependency manager and loader for PHP, Node/XPCOM/JS, Python
* [PublishSubscribe](https://github.com/foo123/PublishSubscribe) a simple and flexible publish-subscribe pattern implementation for Node/XPCOM/JS, PHP, Python, ActionScript
* [Dromeo](https://github.com/foo123/Dromeo) a flexible, agnostic router for Node/XPCOM/JS, PHP, Python, ActionScript
* [Dialect](https://github.com/foo123/Dialect) a simple cross-platform SQL construction for PHP, Python, Node/XPCOM/JS, ActionScript
* [Xpresion](https://github.com/foo123/Xpresion) a simple and flexible eXpression parser engine (with custom functions and variables support) for PHP, Python, Node/XPCOM/JS, ActionScript
* [GrammarTemplate](https://github.com/foo123/GrammarTemplate) versatile and intuitive grammar-based templating for PHP, Python, Node/XPCOM/JS, ActionScript
* [GrammarPattern](https://github.com/foo123/GrammarPattern) versatile grammar-based pattern-matching for Node/XPCOM/JS (IN PROGRESS)
* [Regex Analyzer/Composer](https://github.com/foo123/RegexAnalyzer) Regular Expression Analyzer and Composer for Node/XPCOM/JS, PHP, Python, ActionScript
* [DateX](https://github.com/foo123/DateX) eXtended & localised Date parsing, diffing, formatting and validation for Node/XPCOM/JS, Python, PHP, ActionScript
* [RT](https://github.com/foo123/RT) client-side real-time communication for Node/XPCOM/JS with support for Poll/BOSH/WebSockets
* [Importer](https://github.com/foo123/Importer) simple class & dependency manager and loader for Node.js / Browser / XPCOM Javascript, PHP, Python
* [PublishSubscribe](https://github.com/foo123/PublishSubscribe) a simple and flexible publish-subscribe pattern implementation for Node.js / Browser / XPCOM Javascript, PHP, Python
* [Dromeo](https://github.com/foo123/Dromeo) a flexible, agnostic router for Node.js / Browser / XPCOM Javascript, PHP, Python
* [Dialect](https://github.com/foo123/Dialect) a simple cross-vendor & cross-platform object-oriented SQL Query Builder for Node.js / Browser / XPCOM Javascript, PHP, Python
* [Xpresion](https://github.com/foo123/Xpresion) a simple and flexible eXpression parser engine (with custom functions and variables support) for Node.js / Browser / XPCOM Javascript, PHP, Python
* [GrammarTemplate](https://github.com/foo123/GrammarTemplate) versatile and intuitive grammar-based templating for Node.js / Browser / XPCOM Javascript, PHP, Python
* [GrammarPattern](https://github.com/foo123/GrammarPattern) versatile grammar-based pattern-matching for Node.js / Browser / XPCOM Javascript (IN PROGRESS)
* [Regex Analyzer/Composer](https://github.com/foo123/RegexAnalyzer) Regular Expression Analyzer and Composer for Node.js / Browser / XPCOM Javascript, PHP, Python
* [DateX](https://github.com/foo123/DateX) eXtended & localised Date parsing, diffing, formatting and validation for Node.js / Browser / XPCOM Javascript, PHP, Python
* [RT](https://github.com/foo123/RT) client-side real-time communication for Node/XPCOM/JS with support for Poll / BOSH / WebSockets
* [Asynchronous](https://github.com/foo123/asynchronous.js) a simple manager for async, linearised, parallelised, interleaved and sequential tasks for JavaScript
* [Simulacra](https://github.com/foo123/Simulacra) a simulation, algebraic, probability and combinatorics PHP package for scientific computations

Expand Down Expand Up @@ -66,17 +66,17 @@ A combinatorics library for Node.js / Browser / XPCOM Javascript, PHP, Python, C
* `UnorderedCombination` (`test/combinations.js`)
* `OrderedCombination` / `kPermutation` (`test/ordered_combinations.js`)
* `UnorderedRepeatedCombination` (`test/combinations_repeats.js`)
* `OrderedRepeatedCombination` (`test/ordered_combinations_repeats.js`)
* `OrderedRepeatedCombination` / `kTuple` (`test/ordered_combinations_repeats.js`)
* `Subset` (`test/subsets.js`)
* `Partition` (`test/partitions.js`) **rank/unrank methods missing, partial support for COLEX**
* `Composition` (`test/compositions.js`) **rank/unrank methods missing, partial support for COLEX**
* `RestrictedPartition` (`test/restricted_partitions.js`) **exactly M max. part**
* `RestrictedComposition` (`test/restricted_compositions.js`) **exactly K #parts**
* `LatinSquare` (`test/latin_squares.js`)
* `MagicSquare` (`test/magic_squares.js`)
* **algebraic composition** (of **fixed** dimensions at present) and **sequences** of combinatorial objects to construct new combinatorial objects (eg `all combinations` = `all permutations` **OF** `all unique combinations`, see `test/permutations_of_combinations.js` and `test/permutations_of_permutations.js`, `k-Derangements` = `(n,k) Combinations` **combined With** `(n-k) Derangements`, see `test/k-derangements.js` or `all subsets` = `(n,0)Combinations + (n,1)Combinations + .. + (n,n-1)Combinations + (n,n)Combinations`, see `test/combination_subsets.js`)
* **multiple (combined) iterator orderings & traversals**: `lex`, `colex`, `random`, `reversed`, `reflected`, `minimal` (not implemented yet). For example: `"revlex"` (equivalent to `"lex,reversed"`), `"refcolex"` (equivalent to `"colex,reflected"`), and so on..
* **arbitrary range** of combinatorial objects in a number of supported orderings (ie `lex`, `colex`, `random`,..). **Note** `rank`/`unrank` have to be implemented for this feature to work
* **algebraic composition** of combinatorial objects (of **fixed** dimensions at present) to construct new combinatorial objects (eg `all combinations` = `all permutations` **OF** `all unique combinations`, see `test/permutations_of_combinations.js` and `test/permutations_of_permutations.js`)
* **efficient and unbiased generation, (un)ranking, succession & random methods** for supported combinatorial objects (see below)
* `big-integer arithmetic`, `PRNG`s and other `math` utilities can be **dynamicaly pluggable using external implementations**, making the lib very flexible especialy with respect to handling big-integers & (pseudo-)random number generators

Expand Down
149 changes: 88 additions & 61 deletions src/js/Abacus.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
*
* Abacus
* A combinatorics library for Node.js / Browser / XPCOM Javascript, PHP, Python, Java, C/C++
* @version: 0.9.0
* @version: 0.9.1
* https://github.com/foo123/Abacus
**/
!function( root, name, factory ){
Expand All @@ -22,7 +22,7 @@ else if ( !(name in root) ) /* Browser/WebWorker/.. */
/* module factory */ function ModuleFactory__Abacus( undef ){
"use strict";

var Abacus = {VERSION: "0.9.0"}, stdMath = Math, PROTO = 'prototype', CLASS = 'constructor'
var Abacus = {VERSION: "0.9.1"}, stdMath = Math, PROTO = 'prototype', CLASS = 'constructor'
,slice = Array.prototype.slice, HAS = Object[PROTO].hasOwnProperty, toString = Object[PROTO].toString
,log2 = stdMath.log2 || function(x) { return stdMath.log(x) / stdMath.LN2; }
,trim_re = /^\s+|\s+$/g
Expand Down Expand Up @@ -2587,59 +2587,76 @@ CombinatorialIterator = Abacus.CombinatorialIterator = Class({
return i < item.length ? item[i] : subitem[i-item.length];
}));
}
else if ( ("complete" === method) || ("interleave" === method) || ("combine" === method) )
else if ( ("complete" === method) || ("interleave" === method) || ("join" === method) || ("combine" === method) )
{
// O(n1 + n2)
var n1 = item.length, n2 = subitem.length,
n3 = n1+n2, i2 = 0, i1 = 0, nk = 0,
item_i1 = i1<n1 ? item[i1] : -1,
pos_i1 = null!=POS ? (i1<POS.length ? POS[i1] : -1) : item_i1,
compl = "complete" === method ? complement(BASE, item, true) : null/*array(BASE, 0, 1)*/;
return array(n3, "complete" === method ? function(ii){
// complete
var v;
if ( pos_i1 === ii )
{
v = item_i1;
i1++;
item_i1 = i1<n1 ? item[i1] : -1;
pos_i1 = null!=POS ? (i1<POS.length ? POS[i1] : -1) : item_i1;
}
else
{
v = compl[subitem[i2++]];
}
return v;
} : ("interleave" === method ? function(ii){
// interleave
var v;
if ( pos_i1 === ii )
{
v = item_i1;
i1++;
item_i1 = i1<n1 ? item[i1] : -1;
pos_i1 = null!=POS ? (i1<POS.length ? POS[i1] : -1) : item_i1;
}
else
{
v = subitem[i2++];
}
return v;
} : function(ii){
// combine
var v;
if ( item_i1 === ii )
{
v = item_i1; i1++;
item_i1 = i1<n1 ? item[i1] : -1;
nk++;
}
else
if ( "combine" === method )
{
var items = array(n3, 0, 1), output = array(n3);
for(i1=0; i1<n1; i1++) output[item[i1]] = items[item[i1]];
for(i1=n1-1; i1>=0; i1--) items.splice(item[i1], 1);
i1=0; i2=0;
while(i2 < n2)
{
v = nk + subitem[i2++];
while((i1 < n3) && (null != output[i1])) i1++;
if ( i1 < n3 ) output[i1] = items[subitem[i2]];
i2++;
}
return v;
}));
return output;
}
else
{
return array(n3, "complete" === method ? function(ii){
// complete
var v;
if ( pos_i1 === ii )
{
v = item_i1;
i1++;
item_i1 = i1<n1 ? item[i1] : -1;
pos_i1 = null!=POS ? (i1<POS.length ? POS[i1] : -1) : item_i1;
}
else
{
v = compl[subitem[i2++]];
}
return v;
} : ("interleave" === method ? function(ii){
// interleave
var v;
if ( pos_i1 === ii )
{
v = item_i1;
i1++;
item_i1 = i1<n1 ? item[i1] : -1;
pos_i1 = null!=POS ? (i1<POS.length ? POS[i1] : -1) : item_i1;
}
else
{
v = subitem[i2++];
}
return v;
} : function(ii){
// join
var v;
if ( item_i1 === ii )
{
v = item_i1; i1++;
item_i1 = i1<n1 ? item[i1] : -1;
nk++;
}
else
{
v = nk + subitem[i2++];
}
return v;
}));
}
}
else/*if ( "project" === method )*/
{
Expand Down Expand Up @@ -2751,7 +2768,7 @@ CombinatorialIterator = Abacus.CombinatorialIterator = Class({
$.subcount = Abacus.Arithmetic.mul($.count, $.sub.total());
if ( ("multiply" === method) )
$.subdimension = $.dimension*$.sub.dimension();
else if ( ("add" === method) || ("connect" === method) || ("concat" === method) || ("complete" === method) || ("interleave" === method) || ("combine" === method) )
else if ( ("add" === method) || ("connect" === method) || ("concat" === method) || ("complete" === method) || ("interleave" === method) || ("join" === method) || ("combine" === method) )
$.subdimension = $.dimension+$.sub.dimension();
else
$.subdimension = $.dimension;
Expand Down Expand Up @@ -2790,6 +2807,11 @@ CombinatorialIterator = Abacus.CombinatorialIterator = Class({
return this.fuse("interleave", combIter, pos||this.position(), dir);
}

,joinWith: function( combIter, pos, dir ) {
if ( -1 === pos || 1 === pos ){ dir = pos; pos = null; }
return this.fuse("join", combIter, pos||this.position(), dir);
}

,combineWith: function( combIter, pos, dir ) {
if ( -1 === pos || 1 === pos ){ dir = pos; pos = null; }
return this.fuse("combine", combIter, pos||this.position(), dir);
Expand Down Expand Up @@ -6233,11 +6255,11 @@ LatinSquare = Abacus.LatinSquare = Class({
isLatinSquare: is_latin
,make: function( n ) {
var i, j, k=1, s = new Array(n);
s[0] = new Array(n); for (j=0; j<n; j++) s[0][j] = j+1;
for (i=1; i<n; i++)
//s[0] = new Array(n); for (j=0; j<n; j++) s[0][j] = j+1;
for (i=0; i<n; i++)
{
s[i] = new Array(n);
for (j=0; j<n; j++) s[i][j] = s[0][(j+i)%n];
for (j=0; j<n; j++) s[i][j] = (j+i)%n + 1;
}
return s;
}
Expand All @@ -6262,20 +6284,24 @@ MagicSquare = Abacus.MagicSquare = Class({
,__static__: {
isMagicSquare: is_magic
,make: function magic_square( n ) {
// non-existent
if ( 0 >= n || 2 === n ) return null;
if ( 1 === n ) return [[n]];
// trivial
if ( 1 === n ) return [[1]];

var i, j, k,
odd = n&1, even = 1-odd,
doubly_even = 0 === (n%4),
doubly_even = 0 === (/*n%4*/n&3),
nn = n*n, n2 = (n-odd)>>>1,
O, o, n22, a, b, c, lc, rc, t,
n12, n21, magic;

magic = new Array(n);
for (i=0; i<n; i++) magic[i] = new Array(n);

if ( odd ) // odd order
{
// O(n^2)
n12 = n+n2; n21 = n2+odd;
for (k=0,i=0,j=0; k<nn; k++,j++)
{
Expand All @@ -6286,27 +6312,27 @@ MagicSquare = Abacus.MagicSquare = Class({

else if ( doubly_even ) // doubly-even order
{
// O(n^2)
for (k=0,i=0,j=0; k<nn; k++,j++)
{
if ( j >= n ) { i++; j=0; }
if ( ((i+1)%4)>>>1 === ((j+1)%4)>>>1 )
magic[i][j] = nn-k;
else
magic[i][j] = k+1;
magic[i][j] = (((i+1)/*%4*/&3)>>>1 === ((j+1)/*%4*/&3)>>>1) ? nn-k : k+1;
}
}

else if ( even ) // singly-even order
else //if ( even ) // singly-even order
{
var O = magic_square(n2), o, n22 = n2*n2, a = 2*n22, b = 3*n22, lc, rc, t;
// O((n/2)^2)
O = magic_square(n2); n22 = n2*n2;
a = n22; b = a<<1; c = b+n22;
for (k=0,i=0,j=0; k<n22; k++,j++)
{
if ( j >= n2 ) { i++; j=0; }
o = O[i][j];
magic[i][j] = o;
magic[i+n2][j+n2] = o + n22;
magic[i+n2][j] = o + a;
magic[i][j+n2] = o + b;
magic[i+n2][j+n2] = o + a;
magic[i+n2][j] = o + b;
magic[i][j+n2] = o + c;
}
lc = n2>>>1; rc = lc;
for (j=0; j<n2; j++)
Expand Down Expand Up @@ -6353,6 +6379,7 @@ MagicSquare = Abacus.MagicSquare = Class({
}
return mm;
}
,pythagorean: NotImplemented
}

,n: null
Expand Down
4 changes: 2 additions & 2 deletions src/js/Abacus.min.js

Large diffs are not rendered by default.

52 changes: 26 additions & 26 deletions test/combination_subsets.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Abacus.Subsets via Abacus.Combinations (VERSION = 0.9.0)
Abacus.Subsets via Abacus.Combinations (VERSION = 0.9.1)
---
o = Abacus.CombinatorialIterator([Abacus.Combination(5,0),Abacus.Combination(5,1),Abacus.Combination(5,2),Abacus.Combination(5,3),Abacus.Combination(5,4),Abacus.Combination(5,5)])
o.total()
Expand Down Expand Up @@ -243,38 +243,38 @@ o.order("colex,reversed")
[ 0 ]
[]
o.order("random")
[ 1, 2, 3, 4 ]
[ 1 ]
[ 0, 3, 4 ]
[ 1, 3, 4 ]
[ 0, 1, 2, 4 ]
[ 0, 1, 3, 4 ]
[ 0, 1, 3, 4 ]
[ 2, 1 ]
[ 3, 1 ]
[ 0, 1, 2 ]
[ 2, 3 ]
[ 1, 2 ]
[ 0, 1, 2, 3, 4 ]
[ 3 ]
[ 0, 1, 4 ]
[ 0, 2, 4 ]
[ 4 ]
[ 0, 1, 3 ]
[ 0, 2 ]
[ 0, 1, 2 ]
[ 0, 3, 4 ]
[ 0, 2, 3 ]
[ 2, 3 ]
[ 0, 3, 4 ]
[ 2, 1 ]
[ 0, 1, 3 ]
[ 0, 2, 3 ]
[ 2, 3 ]
[ 1, 2 ]
[ 3, 1 ]
[ 3, 0 ]
[ 1, 2 ]
[ 0, 3, 4 ]
[ 2, 3, 4 ]
[ 2, 3, 4 ]
[ 4, 0 ]
[ 0, 1, 3, 4 ]
[ 1 ]
[ 0, 2, 4 ]
[ 3, 0 ]
[ 4, 3 ]
[ 0, 1, 4 ]
[ 1, 3, 4 ]
[ 1, 3, 4 ]
[ 0, 3, 4 ]
[ 0, 2, 3, 4 ]
[ 2, 4 ]
[ 2, 3 ]
[ 2, 3, 4 ]
[ 0, 1, 4 ]
[ 0 ]
[ 0, 2, 4 ]
[ 2 ]
[ 4, 3 ]
[ 1, 4 ]
[ 4, 1 ]
o.random()
[ 4, 0 ]
[ 0, 1, 2, 4 ]
o.dispose()
Loading

0 comments on commit 869b7cd

Please sign in to comment.