你好,我正在编码代码战争挑战并卡住了。有个问题:
您将获得一系列 6 面骰子。每个骰子都由其代表 面朝上。
计算使所有面都成为所需的最小旋转数 一样。
1 需要旋转一圈才能使 2、3、4 和 5 面朝上,但 需要旋转两次才能使其成为面 6,因为 6 是相反的一面 1.
2 的对边是 5,3 的对边是 4。
我编码了:
function rotations(dieArray) {
let rotations = 0;
const opposites = [
[1, 6],
[2, 5],
[3, 4],
];
// Checking what value most often appears
let countersArr = [];
for (i = 1; i <= 6; i++) {
let counter = 0;
for (j = 0; j < dieArray.length; j++) {
if (dieArray[j] == i) {
counter++;
}
}
countersArr.push(counter);
}
console.log(countersArr);
let maxVal = countersArr[0];
let indexMaxVal = 0;
for (i = 0; i < countersArr.length; i++) {
if (countersArr[i] > maxVal) {
maxVal = countersArr[i];
indexMaxVal = i;
}
}
console.log(
`The number that most often appears is ${
indexMaxVal + 1
}, appears ${maxVal} times.`
);
// finishVal = max of counterArr
const finishval = indexMaxVal + 1;
// Check what opposite array includes finishval
let indexofFinishVal = 0;
opposites.map((x, i) => {
if (x.includes(finishval)) {
indexofFinishVal = i;
}
});
// 2.Check number of rotations to be finishval
for (i = 0; i < dieArray.length; i++) {
if (dieArray[i] == finishval) {
rotations += 0;
} else if (opposites[indexofFinishVal].includes(dieArray[i])) {
rotations += 2;
} else {
rotations++;
}
}
console.log(rotations);
return rotations;
}
我遇到了问题,我想我知道问题出在哪里。我认为我不能只采用像 finishVal 这样的第一个数字,因为可能还有另一个需要更少旋转的选择。我的假设是:取最常出现的值,即finishVal。我测试了我的代码,84 次测试通过,20 次失败。如果我理解这个问题,你能帮我做什么来改变我的代码以使其正常工作吗?
是的,你说得对。你不能只取一个数字,你需要检查所有独特的可能变化。 基本上,整个任务是从给定数组中取出每个数字并翻转所有其他立方体,使它们具有相同的值。这里首先想到的是我们最多有 6 种可能的变体(立方体的最大可能边数),也就是说,我们不需要尝试给定数组中的所有 n 个数字,而只需尝试独特的变体。让我们举个例子: [1, 1, 1, 1, 1, 6] → 我们有结果数组的两个变体,我们可以将所有数字旋转为值 6 或 1,因为唯一的可能值 = {1, 6}:
对每个组合完成此操作后,我们需要应用条件中给出的规则来计算在此过程中进行的旋转次数。 我们来看代码:
function rotations(diceArray){
const uniqueDiceValues = [...new Set(diceArray)]; // options to be checked
const reverseSideTable = new Map([
[1, 6],
[6, 1],
[2, 5],
[5, 2],
[3, 4],
[4, 3],
]);
let bestRotationQuantity = Infinity;
for (const targetDiceValue of uniqueDiceValues) {
let currentRotationQuantity = 0;
for (const diceValue of diceArray) {
if (diceValue === targetDiceValue) {
// we must add 0, no rotates are required,
// so we just do nothing and skip the current iteration.
continue;
}
if (reverseSideTable.get(diceValue) === targetDiceValue) {
// if the reverse side of the current die is equal to our target,
// then we need to make 2 flips.
currentRotationQuantity += 2;
} else {
// all other cases equal 1 flip.
currentRotationQuantity++;
}
}
if (currentRotationQuantity < bestRotationQuantity) {
bestRotationQuantity = currentRotationQuantity;
}
}
return Number.isFinite(bestRotationQuantity) ? bestRotationQuantity : 0;
}
您还可以注意到,骰子值和反转骰子值的总和 = 7,这使我们可以摆脱反向表对象并使用此条件 → diceValue + targetDiceValue === 7。因此,代码可能如下所示这个:
function rotations(diceArray){
const uniqueDiceValues = [...new Set(diceArray)];
let bestRotationQuantity = Infinity;
for (const targetDiceValue of uniqueDiceValues) {
let currentRotationQuantity = 0;
for (const diceValue of diceArray) {
if (diceValue === targetDiceValue) {
continue;
}
if (diceValue + targetDiceValue === 7) {
currentRotationQuantity += 2;
} else {
currentRotationQuantity++;
}
}
if (currentRotationQuantity < bestRotationQuantity) {
bestRotationQuantity = currentRotationQuantity;
}
}
return Number.isFinite(bestRotationQuantity) ? bestRotationQuantity : 0;
}