Генерация сочетаний с заданным размером массива
Допустим, есть массив
m = [3, 6, 9, 12, 15]`
Мне нужно получить все сочетания элементов с повторениями в массивах размера 4, например:
[3, 3, 3, 3]
[3, 3, 3, 6]
[3, 3, 6, 3]
[3, 6, 3, 3]
[6, 3, 3, 3]
[3, 3, 6, 6]
и так далее.
Что я могу предпринять?
Еще было бы замечательно выводить массивы только по определенному условию, например если
{
arr[0]/arr[1] == 2*arr[0]+arr[2]/(2*arr[1]+arr[3]) == 3*arr[0]+2*arr[2]/(3*arr[1]+2*arr[3])) }
return arr;
Ответы (2 шт):
Ну грубое решение будет таким:
let arr = [3, 6, 9, 12, 15];
let res = [];
for( let a = 0; a < arr.length; a++ ) {
for( let b = 0; b < arr.length; b++ ) {
for( let c = 0; c < arr.length; c++ ) {
for( let d = 0; d < arr.length; d++ ) {
res.push( [arr[a], arr[b], arr[c], arr[d]] );
}
}
}
}
document.body.innerHTML = res.join("<br>").replace(/(\d+,3,3,3)/g,"<li>$1");
body { display: flex; }
body li { margin: 10px; list-style: none; }
Но не ставьте галочку: Хорошо бы подумать, и превратить 4 уровня вложенности в параметр, и научиться при необходимости вызывать любое количество вложенных циклов.
Завел массив start = [0, 0, 0, 0] который хранит текущие индексы для исходного массива. Каждый элемент - как-бы цифра, в 5-ричной системе счисления. Т.е. чтобы можно было считать
0, 0, 0, 1
0, 0, 0, 2
0, 0, 0, 3
0, 0, 0, 4
0, 0, 1, 0
...
4, 4, 4, 4
И на каждой итерации на основе этих чисел (индексов) - доставать элементы из исходного массива.
let arr = [3, 6, 9, 12, 15];
let range_limit = 4; // Длина подмассивов;
let index_limit = arr.length - 1;
if( range_limit > index_limit ) throw new Error("Будет бобо");
let result = [];
let start = new Array(range_limit).fill(0); // от [0, 0, 0, 0]
let end = String( new Array(range_limit).fill(index_limit) ); // до [4, 4, 4, 4]
while( true ) {
let x = start.map( index => arr[index] );
if( "Условие-фильтр" ) result.push(x);
if( String(start) === end ) break;
_increment(start);
};
document.body.innerHTML = result.join("<br>").replace(/(\d+,3,3,3)/g,"<li>$1");
/***/
function _increment(arr) {
let i = arr.length - 1;
while( i >= 0 ) {
arr[i]++;
if( arr[i] > index_limit ) {
arr[i] = 0; // Если вышли за пределы системы счисления - сбросить до 0
i--; // На следующем круге - следующий разряд увеличится на 1.
} else {
break; // благополучно увеличили на 1
}
}
}
body { display: flex; }
body li { margin: 10px; list-style: none; }