How to find all partitions of a multiset, where each part has distinct elements in JavaScript

Finding all partitions of a multiset where each part contains distinct elements is a complex combinatorial problem. We need to create an algorithm that generates all possible ways to divide elements into groups without repetition within each group.

Let's say we have an array with repeated elements:

const arr = [A, A, B, B, C, C, D, E];

We need to find all combinations that use the entire array, where no elements are repeated within each partition.

Example Partitions

[A, B, C, D, E] [A, B, C]
[A, B, C, D] [A, B, C, E] 
[A, B, C] [A, B, C] [D, E]

Key Rules

Order Independence: [A, B, C] [A, B, C] [D, E] and [A, B, C] [D, E] [A, B, C] are considered the same partition. Additionally, within subsets, [A, B, C] and [B, A, C] are identical.

Implementation

Here's the complete algorithm that handles multiset partitioning:

const arr = [['A', 1], ['B', 2], ['C', 3]];

const spread = (arr, ind, combination) => {
    if (arr[1] === 0)
        return [combination];
    if (ind === -1)
        return [combination.concat([arr])];
    
    let result = [];
    for (let c = 1; c <= Math.min(combination[ind][1], arr[1]); c++) {
        let comb = combination.map(x => x.slice());
        if (c == comb[ind][1]) {
            comb[ind][0] += arr[0];
        } else {
            comb[ind][1] -= c;
            comb.push([comb[ind][0] + arr[0], c]);
        }
        result = result.concat(spread([arr[0], arr[1] - c], ind - 1, comb));
    }
    let comb = combination.map(x => x.slice());
    return result.concat(spread(arr, ind - 1, comb));
};

const helper = arr => {
    function inner(ind) {
        if (ind === 0)
            return [[arr[0]]];
        const combs = inner(ind - 1);
        let result = [];
        for (let comb of combs)
            result = result.concat(spread(arr[ind], comb.length - 1, comb));
        return result;
    }
    return inner(arr.length - 1);
};

const returnPattern = (arr = []) => {
    const rs = helper(arr);
    const set = new Set();
    
    for (let r of rs) {
        const _r = JSON.stringify(r);
        if (set.has(_r))
            console.log('Duplicate: ' + _r);
        set.add(_r);
    }
    
    let str = '';
    for (let r of set)
        str += '<br>' + r
    str += '<br><br>';
    return str;
};

console.log(returnPattern(arr));

Output

[["ABC",1],["BC",1],["C",1]]
[["AB",1],["BC",1],["C",2]]
[["ABC",1],["B",1],["C",2]]
[["AB",1],["B",1],["C",3]]
[["AC",1],["B",1],["BC",1],["C",1]]
[["A",1],["B",1],["BC",1],["C",2]]
[["AC",1],["BC",2]]
[["A",1],["BC",2],["C",1]]
[["AC",1],["B",2],["C",2]]
[["A",1],["B",2],["C",3]]

How It Works

The algorithm uses recursive backtracking:

  • Input Format: Each element is represented as [character, count] pairs
  • Spread Function: Distributes remaining elements across existing partitions
  • Helper Function: Recursively builds all possible partition combinations
  • Duplicate Removal: Uses JSON stringification and Set to eliminate identical partitions

Conclusion

This algorithm efficiently generates all distinct partitions of a multiset where each part contains unique elements. The recursive approach with backtracking ensures all valid combinations are found while avoiding duplicates.

Updated on: 2026-03-15T23:19:00+05:30

292 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements