骰子旋转的最小次数

问题描述 投票:0回答:1

你好,我正在编码代码战争挑战并卡住了。有个问题:

您将获得一系列 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 次失败。如果我理解这个问题,你能帮我做什么来改变我的代码以使其正常工作吗?

javascript rotation dice
1个回答
0
投票

是的,你说得对。你不能只取一个数字,你需要检查所有独特的可能变化。 基本上,整个任务是从给定数组中取出每个数字并翻转所有其他立方体,使它们具有相同的值。这里首先想到的是我们最多有 6 种可能的变体(立方体的最大可能边数),也就是说,我们不需要尝试给定数组中的所有 n 个数字,而只需尝试独特的变体。让我们举个例子: [1, 1, 1, 1, 1, 6] → 我们有结果数组的两个变体,我们可以将所有数字旋转为值 6 或 1,因为唯一的可能值 = {1, 6}:

  1. [1, 1, 1, 1, 1, 1]
  2. [6,6,6,6,6,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;
}
© www.soinside.com 2019 - 2024. All rights reserved.