我在 HackerRank 上的 Project Euler #1 测试用例上遇到了一些问题,希望有一些 JS 经验的 HackerRank 可以帮忙。
下面是我的代码。据我所知,我无法发现任何明显的逻辑错误,因此如果有人能够解释为什么我没有通过所有测试用例以及为什么状态是“中止调用”,我将不胜感激。上面“忽略此行上方”的所有代码均由 HackerRank 提供,不属于解决方案的一部分。
process.stdin.resume();
process.stdin.setEncoding('ascii');
var input_stdin = "";
var input_stdin_array = "";
var input_currentline = 0;
process.stdin.on('data', function (data) {
input_stdin += data;
});
process.stdin.on('end', function () {
input_stdin_array = input_stdin.split("\n");
main();
});
function readLine() {
return input_stdin_array[input_currentline++];
}
/////////////// ignore above this line ////////////////////
function threeFiveMultiples(num) {
let array = [];
for (let i = 0; i < num; i++) {
if (i % 3 === 0 ||
i % 5 === 0) {
array.push(i);
}
}
return array.reduce(function(accum, currVal) {
return accum + currVal;
});
}
function main() {
var t = parseInt(readLine());
for(var a0 = 0; a0 < t; a0++){
var n = parseInt(readLine());
let res = threeFiveMultiples(n);
console.log(res);
}
}
我还尝试过使用 BigNumbers 库(见下文)。
process.stdin.resume();
process.stdin.setEncoding('ascii');
var BigNumber = require('bignumber.js');
var input_stdin = "";
var input_stdin_array = "";
var input_currentline = 0;
process.stdin.on('data', function (data) {
input_stdin += data;
});
process.stdin.on('end', function () {
input_stdin_array = input_stdin.split("\n");
main();
});
function readLine() {
return input_stdin_array[input_currentline++];
}
/////////////// ignore above this line ////////////////////
function threeFiveMultiples(num) {
let array = [];
for (let i = 0; i < num; i++) {
if (i % 3 === 0 ||
i % 5 === 0) {
array.push(i);
}
}
return parseInt(array.reduce(function(accum, currVal) {
accum = new BigNumber(accum);
currVal = new BigNumber (currVal);
return accum.plus(currVal);
}));
}
function main() {
var t = parseInt(readLine());
for(var a0 = 0; a0 < t; a0++){
var n = parseInt(readLine());
let res = threeFiveMultiples(n);
console.log(res);
}
}
更新:
根据@5ar的建议,我用以下内容替换了我的reduce函数;然而,测试用例 #2 和 #3 仍然失败:
return array.reduce(function(accum, currVal) {
return accum.plus(currVal);
}, new BigNumber(0)).toString();
你的代码没问题。 如果你简单地调用 console.log( ThreeFiveMultiples(1000)); ,它会给你解决方案。不确定所有其他代码是关于什么的,但这会起作用。
尝试对您的值使用
Math.round()
(求和后),JavaScript 将所有数字视为双精度数,因此某些数字可能无法正确显示。
如果问题是大数字,请尝试找到一个可以处理大数字的库。如果你不能,你可以通过字符串自己实现它们,考虑到你只需要求和它应该不会那么困难。
更新:
我认为返回可能是问题所在(您正在使用
parseInt
,它可能将 BigNumber 转换为字符串,然后尝试将其解析为数字),尝试这样做:
return array.reduce(function(accum, currVal) {
return accum.plus(currVal);
}, new BigNumber(0)).toString();
问题在于,对于非常大的数字,计算会占用相当多的时间,而 hackerrank 的计算超时时间为
10s
。您必须找到一种更快的方法来计算正确的输出。
一个小提示:算术级数(在
O(1)
中是可能的)
您的代码失败有两个可能的原因
1) 超时错误 您编写的代码逻辑会迭代每个数字并检查它是否可以被 3 或 5 整除。当测试用例中的数字很大时,此逻辑会导致超时错误。
2)数字无法在JS中表示 测试用例3和测试用例2中使用的数字是一个很大的数字。因此,使用像“bignumber.js”这样的库是必要的,因为 JS 不支持长整数。
下面是有助于通过所有测试用例的代码片段:
process.stdin.resume();
process.stdin.setEncoding('ascii');
var input_stdin = "";
var input_stdin_array = "";
var input_currentline = 0;
process.stdin.on('data', function (data) {
input_stdin += data;
});
process.stdin.on('end', function () {
input_stdin_array = input_stdin.split("\n");
main();
});
function readLine() {
return input_stdin_array[input_currentline++];
}
/////////////// ignore above this line ////////////////////
function main() {
var BigNumber = require('bignumber.js');
var t = new BigNumber(readLine()).toNumber();
var n;
for (var a0 = 0; a0 < t; a0++) {
n = new BigNumber(readLine());
sumOfNumberDivisibleBy3and5(n);
}
}
function sumOfNumberDivisibleBy3and5(n) {
const a = n.minus(1).dividedBy(3).floor();
const b = n.minus(1).dividedBy(5).floor();
const c = n.minus(1).dividedBy(15).floor();
const sumThree = a.times(3).times(a.plus(1)).dividedBy(2);
const sumFive = b.times(5).times(b.plus(1)).dividedBy(2);
const sumFifteen = c.times(15).times(c.plus(1)).dividedBy(2);
const sumOfAll = sumThree.plus(sumFive).minus(sumFifteen);
console.log(sumOfAll.toString());
}
这对我有用
function main() {
var t = parseInt(readLine());
for(var a0 = 0; a0 < t; a0++){
var n = parseInt(readLine());
/////////////////they forgot to tell us to put code below here
let N=BigInt(n)-BigInt(1)
let i3=BigInt(N)/BigInt(3)
let i5=BigInt(N)/BigInt(5)
let i15=BigInt(N)/BigInt(15)
let m3=BigInt(3)*BigInt(i3)*(BigInt(i3)+BigInt(1))
let m5=BigInt(5)*BigInt(i5)*(BigInt(i5)+BigInt(1))
let m15=BigInt(15)*BigInt(i15)*(BigInt(i15)+BigInt(1))
let sum=(BigInt(m3)+BigInt(m5)-BigInt(m15))/BigInt(2)
console.log(sum.toString())
/////////////////they forgot to tell us to put code above here
}
}
// Having to use BigInt to handle the caculation for huge numbers.
console.log(Number.MAX_SAFE_INTEGER);
var n = 999999999999999999999n;
var m = BigInt(n) - 1n; // We need numbers strictly below n
var numberOf3 = m / 3n;
var numberOf5 = m / 5n;
var numberOf15 = m / 15n;
var sum3 = 3n * numberOf3 * (numberOf3 + 1n) / 2n;
var sum5 = 5n * numberOf5 * (numberOf5 + 1n) / 2n;
var sum15 = 15n * numberOf15 * (numberOf15 + 1n) / 2n;
var sum = sum3 + sum5 - sum15;
console.log(sum.toString());