find all combination of array items upto n number and array item can be repeated

Viewed 101

I have array like ['PP', 'PT, 'CK']. And I have number n. For example it is 4. I want to generate all combinations of array items upto 4 so output would be something like below having all combinations

[['PP', 'PP', 'PP', 'PP'],

['PP', 'PP', 'PP', 'PT'],

['PP', 'PP', 'PT', 'PT'],

['PP', 'PT', 'PT', 'PT'],

['PT', 'PT', 'PT', 'PT'],

['PP', 'PP', 'PP', 'CK'],

['PP', 'PP', 'CK', 'CK'],

['PP, 'CK', 'CK', 'CK'],

['CK', 'CK', 'CK', 'CK'],

['PT', 'CK', 'CK', 'PP'],

['PT', 'PT', 'CK', 'PP],

['PT', 'PT', 'PT', 'CK']]

I tried writing below code but it is not giving me expected output

const getCombination = (arr, n) => {
  const list = [];
  if (arr.length === 1) {
    const items = [];
    for (let t = 0; t < n; t++) {
      items.push(arr[0]);
    }
    list.push(items);
    return list;
  }
  for (let i = n; i >= 0; i--) {
    let k = i;
    const items = [];
    while (k > 0) {
      items.push(arr[0]);
      k--;
    }
    if (i === n) {
      list.push(items);
      continue;
    }
    let c = n - i;
    let val = 1;
    if (i === 0) {
      val = 0;
    }
    for (let j = val; j < arr.length; j++) {
      const op = [...items];
      const l = arr[j];
      let p = 0;
      let isRun = false;
      if (j === 0) {
        continue;
      }
      while (p < c && items.length < n) {
        op.push(l);
        p++;
        isRun = true;
      }
      if (isRun) list.push(op);
    }
  }
  return list;
}

console.log("list", getCombination(["PP", "PT", "CK"], 4));

1 Answers

You could take a recursion which returns either an array with the last item with the leftover count or iterate the number of possible counts of the actual element.

Then push the mapped result of new array to the result set.

Result with unique count of items.

PP PP PP PP
PP PP PP PT
PP PP PP CK
PP PP PT PT
PP PP PT CK
PP PP CK CK
PP PT PT PT
PP PT PT CK
PP PT CK CK
PP CK CK CK
PT PT PT PT
PT PT PT CK
PT PT CK CK
PT CK CK CK
CK CK CK CK

const
    getCombinations = ([item, ...array], n) => {
        if (!array.length) return [Array(n).fill(item)];

        const result = [];
        let m = n;

        do {
            const left = Array(m).fill(item);
            result.push(...getCombinations(array, n - m)
                .map(right => [...left, ...right])
            );
        } while (m--);

        return result;
    },
    result = getCombinations(["PP", "PT", "CK"], 4);

result.forEach(a => console.log(...a));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Related