gpt4 book ai didi

javascript - 使用 Javascript 的 Codewars 除法 Kata 生成的结果不能被 6 整除

转载 作者:行者123 更新时间:2023-12-01 00:30:32 27 4
gpt4 key购买 nike

我正在尝试解决 Codewars 中的这个 Kata:https://www.codewars.com/kata/simple-fun-number-258-is-divisible-by-6/train/javascript

这个想法是,将一个数字(表示为字符串)的一位数字替换为*,例如“1047*66”,将被插入到函数中。您必须返回一个数组,其中的值是原始数字,并将 * 替换为任何能除以 6 的数字。因此,给定“1*0”,正确的结果数组应该是 [120, 150, 180] .

我有一些代码产生了一些正确的结果,但对其他结果却产生了错误,我不明白为什么。代码如下:

function isDivisibleBy6(s) {

var results = [];

for(i=0;i<10;i++) {

var string = i.toString(); // Convert i to string, ready to be inserted into s
var array = Array.from(s); // Make an array from s
var index = array.indexOf("*"); // Find where * is in the array of s
array[index] = string; // Replace * with the string of i

var number = array.join(""); // Join all indexes of the s array back together. Now we should have
// a single number expressed as a string, with * replaced with i

parseInt(number, 10); // Convert the string to an integer

if((number % 6) == 0) {
results.push(number);
} // If the integer is divisible by 6, add the integer into the results array

}
return(results);
};

此代码适用于上面的示例,并且通常适用于所有较小的数字。但它会在较大的数字上产生错误。例如,当 s 为“29070521868839*57”时,输出应为 []。但是,我得到 ['29070521868839257','29070521868839557','29070521868839857']。我不明白这会出什么问题。有人可以帮忙吗?

最佳答案

问题是这些数字大于 Number.MAX_SAFE_INTEGER - JavaScript 数字在可靠性方面崩溃的时刻:

var num = 29070521868839257;
console.log(num > Number.MAX_SAFE_INTEGER);
console.log(num % 6);
console.log(num)

最后一条日志显示num实际上它的值与我们赋予它的值不同。这是因为29070521868839257根本无法用 JavaScript 数字表示,因此您会得到可以表示的最接近的可能值,即 29070521868839256 .

因此,在数字中的某个点之后,所有数学运算都变得不可靠,因为这些数字不精确

您可以做的就是忽略将整个数字视为数字 - 将其视为字符串并仅应用 principles of divisibility 。这使得任务变得更加容易。

对于可被6整除的数字它必须涵盖两个标准:

  • 它必须能被2整除。
    • 要验证这一点,您只需获取最小的数字并检查它是否可以被 2 整除。 。例如29070521868839257如果我们取 7 ,然后检查7 % 2 ,我们得到1这意味着这很奇怪。我们不需要考虑整个数字。
  • 它必须能被3整除。
    • 为了验证这一点,您可以对每个数字求和,看看该和是否能被 3 整除。 。如果我们将 29070521868839257 中的所有数字相加我们得到2 + 9 + 0 + 7 + 0 + 5 + 2 + 1 + 8 + 6 + 8 + 8 + 3 + 9 + 2 + 5 + 7 = 82不能被3整除。如果有疑问,我们可以再次对数字进行求和,因为该规则可以应用于任何超过两位数的数字:8 + 2 = 101 + 0 = 1 。这仍然不能被3整除.

所以,如果我们应用这些,我们可以得到类似的结果:

function isDivisibleBy6(s) {
return isDivisibleBy2(s) && isDivisibleBy3(s);
};

function isDivisibleBy2(s) {
var lastDigit = Number(s.slice(-1));

return (lastDigit % 2) === 0;
}

function isDivisibleBy3(s) {
var digits = s.split("")
.map(Number);

var sum = digits.reduce(function(a, b) {
return a + b
});

return (sum % 3) === 0;
}

console.log(isDivisibleBy6("29070521868839257"));
console.log(isDivisibleBy6("29070521868839256"));

这些甚至可以根据这些规则的本质进行递归定义:

function isDivisibleBy6(s) {
return isDivisibleBy2(s) && isDivisibleBy3(s);
};

function isDivisibleBy2(s) {
if (s.length === 0) {
return false;
}

if (s.length > 1) {
return isDivisibleBy2(s.slice(-1));
}

var lastDigit = Number(s);
return (lastDigit % 2) === 0;
}

function isDivisibleBy3(s) {
if (s.length === 0) {
return false;
}

if (s.length > 1) {
var digits = s.split("")
.map(Number);

var sum = digits.reduce(function(a, b) {
return a + b
});

return isDivisibleBy3(String(sum));
}

var num = Number(s);
return (num % 3) === 0;
}

console.log(isDivisibleBy6("29070521868839257"));
console.log(isDivisibleBy6("29070521868839256"));

这纯粹是为了演示除法规则以及如何将它们应用于字符串。您必须创建可被 6 整除的数字为此,您必须替换星号。最简单的方法就像你所做的那样 - 生成所有可能性(例如, 1*0 将是 100110120130140150160 , 170180190 ),然后过滤掉不能被 6 整除的内容:

function isDivisibleBy6(s) {
var allDigits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

var allPossibleNumbers = allDigits.map(function(digit) {
return s.replace("*", digit);
});

var numbersDibisibleBySix = allPossibleNumbers.filter(function(s) {
return isDivisibleBy2(s) && isDivisibleBy3(s);
})

return numbersDibisibleBySix;
};

function isDivisibleBy2(s) {
var lastDigit = Number(s.slice(-1));

return (lastDigit % 2) === 0;
}

function isDivisibleBy3(s) {
var digits = s.split("")
.map(Number);

var sum = digits.reduce(function(a, b) {
return a + b
});

return (sum % 3) === 0;
}

console.log(isDivisibleBy6("29070521868839*57"));
console.log(isDivisibleBy6("29070521868839*56"));

最后一点,可以通过删除中间值并使用箭头函数来编写更简洁的代码:

function isDivisibleBy6(s) {
return [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
.map(digit => s.replace("*", digit))
.filter(s => isDivisibleBy2(s) && isDivisibleBy3(s));
};

const isDivisibleBy2 = s => Number(s.slice(-1)) % 2 === 0;

const isDivisibleBy3 = s => s.split("")
.map(Number)
.reduce((a, b) => a + b) % 3 === 0

console.log(isDivisibleBy6("29070521868839*57"));
console.log(isDivisibleBy6("29070521868839*56"));

关于javascript - 使用 Javascript 的 Codewars 除法 Kata 生成的结果不能被 6 整除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58588389/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com