HackerRank上的JavaScript项目Euler#1

时间:2017-10-22 01:28:32

标签: javascript functional-programming precision

我对HackerRank上的Project Euler#1的测试用例有些麻烦,并且希望有一些在HackerRank上有JS经验的人可以提供帮助。

Click here to see the test case results

以下是我的代码。据我所知,我无法发现任何明显的逻辑错误,所以如果有人能够解释为什么我没有通过所有的测试用例以及为什么状态是"我会很感激。中止叫#34;以上所有代码"忽略此行"由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();

4 个答案:

答案 0 :(得分:2)

你的代码很好。如果您只是调用console.log(threeFiveMultiples(1000));,它将为您提供解决方案。不确定所有其他代码是什么,但这将有效。

答案 1 :(得分:2)

尝试在您的值上使用Math.round()(在对它们求和之后),JavaScript会将所有数字视为双精度数,因此某些数字可能无法正确显示。

如果问题是大数字,请尝试找一个可以处理大数字的库。如果你不能,你可以通过字符串自己实现它们,考虑到你只需要求它就不应该那么困难。

<强>更新

我认为返回可能是问题(你使用parseInt可能会将BigNumber转换为String,然后尝试将其解析为Number),尝试这样做:

return array.reduce(function(accum, currVal) {
    return accum.plus(currVal);
}, new BigNumber(0)).toString();

答案 2 :(得分:0)

问题在于,对于非常大的数字,计算占用了相当长的时间,而hackerrank的计算超时为10s。你必须找到一种更快的计算正确输出的方法。

一个小提示:算术进展(可能在O(1)中)

答案 3 :(得分:0)

代码失败有两个可能的原因

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());
}