一定數量的猴子圍成一圈,以某個猴子開始從1號順序編號。兩個骰子隨機擲出一個數,從1號開始數,數到骰子數的猴子出局,從下一個猴子繼續(xù)從1開始數,再次數到骰子數的猴子出局,以此類推,最后剩下一個猴子。計算每個猴子成為最后被剩下的概率?可同時計算多個猴子數的不同概率。
const calcNumPR = (count = 2) => (...monkeys) => monkeys.reduce((origin, item) => {
// 生成指定個數的數字集合 [1, 2, 3]
const originNumbers = [...new Array(item)].map((item, i) => i + 1);
// 最后剩下號碼集合
let lastNumbers = [];
// 默認2(count)個骰子,共 11(count * 6 - 1)種情況(2、3、4、5、6、7、8、9、10、11、12)
for (let i = count; i <= count * 6; i++) {
// 每次獲取全新集合
const currentNumbers = Object.assign([], originNumbers);
// 默認去除位置為 -1,step 基數為當前變量
let [pos, step] = [-1, i];
for (let j = 0; j < currentNumbers.length; j++) {
// 計算需要去除號碼的位置
pos += step;
// 如果號碼位置超過當前剩余數,則再從頭開始數
while (pos > currentNumbers.length - 1) {
pos -= currentNumbers.length;
}
// 如果不是最后一個,則根據取出位置刪除剩余元素,之后當前位置-1,當前循環(huán)變量-1
if (currentNumbers.length > 1) {
currentNumbers.splice(pos, 1);
pos--;
j--;
}
}
// 將每個骰子最后剩余號碼加入到集合中
lastNumbers = [...lastNumbers, ...currentNumbers];
}
// 計算剩余號碼集合中每個數字在11次機會重的概率
origin[item] = originNumbers.map(originNumber => {
const targetNumbers = lastNumbers.filter(lastNumber => lastNumber == originNumber);
return {[originNumber]: targetNumbers.length ? (targetNumbers.length / 11 * 100).toFixed(2) + '%' : 0};
});
return origin;
}, {});
const numbers = calcNumPR(1)(6, 8);
console.log(numbers);
// {
// '6': [
// {'1': '18.18%'},
// {'2': 0},
// {'3': 0},
// {'4': '9.09%'},
// {'5': '18.18%'},
// {'6': '9.09%'},
// ],
// '8': [
// {'1': '18.18%'},
// {'2': 0},
// {'3': '9.09%'},
// {'4': 0},
// {'5': 0},
// {'6': '9.09%'},
// {'7': '9.09%'},
// {'8': '9.09%'},
// ],
// };
以上為代碼演示,歡迎指正!