console.log = function(...args){
document.writeln(args);
document.writeln('<br/>');
}
/**
* 类似全排列
*
* */
function swap(arr, index1, index2) {
[
arr[index2], arr[index1]
] = [
arr[index1], arr[index2]
];
}
// 两数混合加减乘除
function get2NumsFormula(a, b, isOuter = false) {
const base = [
`(${a}-${b})`,
`(${a}+${b})`,
`(${a}*${b})`,
`(${a}/${b})`,
`(${b}-${a})`,
// `(${b}+${a})`, // 运算结果相同
// `(${b}*${a})`, // 运算结果相同
`(${b}/${a})`,
];
if (!isOuter) {
base.push(
`(${b}+${a})`,
);
}
return base;
}
function get3NumsFormula(a, b, c) {
"use strict"; // arguments分离
// 3个数全排列 * 符号数量 * 符号数量
const formulas = [];
let end = 6;
// 333
if (a === b && b === c) {
end = 1;
}
// 数字重复只有3种组合~
// 233 -> 332 -> 323
if (a === b || b === c || a === c) {
end = 3;
}
for (let i = 0; i < end; i++) {
// 123
if (i === 0) {
formulas.push(
`(${a}+${b}+${c})`,
`(${a}*${b}*${c})`,
);
}
// 231
if (i === 1) {
a = arguments[1];
b = arguments[2];
c = arguments[0];
}
// 312
if (i === 2) {
a = arguments[2];
b = arguments[0];
c = arguments[1];
}
// 另一半
// 321
if (i === 3) {
a = arguments[2];
b = arguments[1];
c = arguments[0];
}
// 132
if (i === 4) {
a = arguments[1];
b = arguments[0];
c = arguments[2];
}
// 213
if (i === 5) {
a = arguments[0];
b = arguments[2];
c = arguments[1];
}
formulas.push(
// `(${a}+${b}+${c})`,
`(${a}+${b}-${c})`,
// `(${a}+(${b}+${c}))`,
// `(${a}+(${b}-${c}))`,
`(${a}+${b}*${c})`,
`(${a}+${b}/${c})`,
// `((${a}+${b})*${c})`,
// `((${a}+${b})/${c})`,
`(${a}-${b}+${c})`,
`(${a}-${b}-${c})`,
// `(${a}-(${b}+${c}))`,
`(${a}-(${b}-${c}))`,
`(${a}-${b}*${c})`,
`(${a}-${b}/${c})`,
// `((${a}-${b})*${c})`,
// `((${a}-${b})/${c})`,
`(${a}*${b}+${c})`,
`(${a}*${b}-${c})`,
`(${a}*(${b}+${c}))`,
`(${a}*(${b}-${c}))`,
// `(${a}*${b}*${c})`,
`(${a}*${b}/${c})`,
// `((${a}*${b})*${c})`,
// `((${a}*${b})/${c})`,
`(${a}/${b}+${c})`,
`(${a}/${b}-${c})`,
`(${a}/(${b}+${c}))`,
`(${a}/(${b}-${c}))`,
`(${a}/${b}*${c})`,
`(${a}/${b}/${c})`,
// `((${a}/${b})*${c})`,
// `((${a}/${b})/${c})`,
);
}
return formulas;
}
function main(arr, sum = 24) {
let tag = '';
function permutation(arr, arrIndex) {
// if (arrIndex === arr.length - 2) {
// return get2NumsFormula(arr[arrIndex], arr[arrIndex + 1]);
// }
if (arrIndex === arr.length - 3) {
return get3NumsFormula(arr[arrIndex], arr[arrIndex + 1], arr[arrIndex + 2]);
}
let curPermutations = [];
const headHistoryStore = {};
for (let i = arrIndex; i < arr.length; i++) {
swap(arr, arrIndex, i);
tag = arr.slice(arrIndex).toString();
if (headHistoryStore[arr[arrIndex]]) {
swap(arr, arrIndex, i);
continue;
} else {
headHistoryStore[arr[arrIndex]] = 1;
}
const childPermutations = permutation(arr, arrIndex + 1);
childPermutations.forEach(per => {
curPermutations = curPermutations.concat(get2NumsFormula(per, arr[arrIndex], arrIndex === 0));
});
swap(arr, arrIndex, i);
}
return curPermutations;
}
const permutations = permutation(arr, 0);
return permutations.filter(per => eval(per) === sum);
}
console.time('test run');
console.log(main([5, 5, 5, 1]));
console.timeEnd('test run');
console.time('test run');
console.log(main([4, 6, 8, 10]));
console.timeEnd('test run');
console.time('test run');
console.log(main([10, 10, 4, 4]));
console.timeEnd('test run');
console.time('test run');
console.log(main([2, 3, 10, 10]));
console.timeEnd('test run');
// TODO 输入数字重复的时候,怎么去重?
// console.log(get3NumsFormula(1, 2, 3).toString());
const result = main([0, 24, 0, 1]);
const result2 = Array.from(new Set(result));
const hasRepeated = result.length !== result2.length;
console.log('是否重复有重复项:', hasRepeated);
console