-1

How do I handle the recursive call without exceeding the call stack size?

This question was answered here Maximum call stack size exceeded error, but has not been helpful to me. It may be helpful to someone else.

The algorithm prompt is a tad lengthy but for those of you that are determined: coin algorithm

My code may DOES NOT attempt to meet all the requirements, but regardless I'd like some input on what I have.

var gameSetup = {
        coins: [2,333,4,11,99,20,10],
        minOdds: 1,
        maxOdds: 100000
}
function game(gs) {
        this.minOdds = gs.minOdds;
        this.maxOdds = gs.maxOdds;

        var coinArray = gs.coins;
        var coinArrayLength = coinArray.length;
        var indicesToSplice = [];

        var gameResults = {
                turns: 0,
                score: 0
        }

        var gameFunctions = {
                getTurns: function() {
                        return gameResults.turns;
                },
                setTurns: function() {
                        ++gameResults.turns;
                },
                setScore: function(lcv,rcv) {
                        var score = lcv * rcv;
                        gameResults.score += score;

                },
                getScore: function() {
                        return gameResults.score;

                },
                generateFlips: function() {
                        return generateFlips.getRandomNumbersInclusive();
                }

        }
        var generateFlips = (function() {
                var flips = [];
                        return {
                                getRandomNumbersInclusive: function() {
                                        flips = [];
                                        for(i=0; i < coinArrayLength; i ++){
                                                var currentFlip = Math.floor(Math.random() * (maxOdds - minOdds + 1)) + minOdds;
                                                flips.splice(0,0,currentFlip);
                                        }
                                return flips;
                                }
                        }
        })();
        (function takeTurn(coinArrayLength) {
                var flips = gameFunctions.generateFlips();


                flips.forEach(function(i, index) {
                        if(i == maxOdds) {
                                var leftOfIndex = flips[index-1];
                                var rightOfIndex = flips[index +1];
                                if(typeof leftOfIndex  === 'undefined' || typeof rightOfIndex  === 'undefined') {

                                } else {
                                        indicesToSplice.splice(0,0,index);
                                        var leftCoinValue = coinArray[index-1];
                                        var rightCoinValue = coinArray[index+1];
                                        gameFunctions.setScore(leftCoinValue,rightCoinValue);
                                }

                        }

                });



                if(indicesToSplice.length > 0) {
                        indicesToSplice.forEach(function(i){
                                coinArray.splice(i,1);
                                coinArrayLength = coinArray.length;
                        });
                }
                indicesToSplice = [];
                gameFunctions.setTurns();

                if(coinArrayLength > 2) {
                        takeTurn(coinArrayLength);
                } else {
                        return;

                }

        })(coinArrayLength);


}
game(gameSetup);
Community
  • 1
  • 1
  • 3
    You have to read [ask] – Amit Feb 19 '16 at 12:52
  • If the code works this might be better off being asked at http://codereview.stackexchange.com/ – Andy Feb 19 '16 at 13:02
  • @Andy the maximum call stack size is exceeded. Node throws a range error. – Anthony Thomas Feb 19 '16 at 13:10
  • @Amit Sorry, im a noob. I will review. – Anthony Thomas Feb 19 '16 at 13:11
  • @Amit what's exactly wrong with the way OP asked this question? He definitely showed that he invested some time and effort into trying to solve the problem, so why the negative votes? – eAbi Feb 19 '16 at 14:11
  • Also, shouldn't we provide some constructive criticism in the comments section before pressing the downvote? e.g. What exactly produces the call stack size exceeded error? Even not understanding what the question is, you might also state this as well. – eAbi Feb 19 '16 at 14:15
  • @eAbi. Thank you for commenting on the importance of constructive criticism. – Anthony Thomas Feb 19 '16 at 14:21
  • @eAbi The call stack size exceeded is produced by the callback - takeTurn(coinArray)- This is my analysis, as that i am not proficient in javascript, i have deduced this from the following error thrown by node: function nextTick(callback) { RangeError: Maximum call stack size exceeded – Anthony Thomas Feb 19 '16 at 14:24
  • `console.log(coinArrayLength)` towards the end of the code, inside the `if(coinArrayLength > 2)`. You're calling this function recursively, but as far as I can tell you aren't decreasing it's size, so every loop will run another takeTurn() – chrisbajorin Feb 19 '16 at 14:43
  • also, `splice(0,0,x)` is equivalent to `unshift(x)` – chrisbajorin Feb 19 '16 at 14:47
  • @eAbi - have a peek at the guide yourself if my comment or the community's votes seem wrong to you. Basically, a question should be a lot more focused and concise then this. – Amit Feb 19 '16 at 15:51
  • 1
    @Amit - Is the modified question now acceptable? cdbajorin was constructive and helpful in furthering my understanding of the language as well as eAbi attempt to pinpoint exactly what that question should be. As a newcomer, it is sometimes difficult to ask the 'right questions' when you do not know what they are. Sympathy for someone new to stackoverflow should be taken into consideration. A downvote does not do anything to promote learning in this circumstance. A simple comment would have sufficed and the corrected measures would have been taken, and as in this case were taken. – Anthony Thomas Feb 19 '16 at 16:21
  • @AnthonyThomas - it is my opinion that no, this is not a good question. You should ask very specific questions, include all relevant information **in the question itself** (that means, don't link to important information) and keep the commentary to the minimum (that means, a question that **didn't help you** and has little to do with your problem isn't interesting). Also, create a minimal version of your problem, not a full algorithm implementation - it's too long. And if you absolutely have to include it all, at least provide useful comments and point out exactly where the problem is. – Amit Feb 19 '16 at 19:13
  • Also, if your problem is that you need to implement an algorithm, ask about the algorithm. If it's about recursion, ask about recursion. Asking about both is not as useful. Also, if you don't really have a problem, you just want a better implementation, stack overflow **is not the place** to ask about it. And as I wrote before, this, and more is in the guide - read it. – Amit Feb 19 '16 at 19:16
  • @Amit. Thanks for the feedback – Anthony Thomas Feb 20 '16 at 13:41

1 Answers1

1

How do I handle the recursive call without exceeding the call stack size?

You don't make it recursive. There is no state that needs to be preserved excluding coinArrayLength, which can be done with a while loop.

while (coinArrayLength > 2) {

    var flips = gameFunctions.generateFlips();

    flips.forEach(function(i, index) {
        if(i === maxOdds) {
            var leftOfIndex = flips[index-1];
            var rightOfIndex = flips[index +1];
            if(typeof leftOfIndex  === 'undefined' || typeof rightOfIndex  === 'undefined') {


            } else {
                indicesToSplice.splice(0,0,index);
                var leftCoinValue = coinArray[index-1];
                var rightCoinValue = coinArray[index+1];
                gameFunctions.setScore(leftCoinValue,rightCoinValue);
            }
        }
    });

    if(indicesToSplice.length > 0) {
        indicesToSplice.forEach(function(i){
            coinArray.splice(i,1);
            coinArrayLength = coinArray.length;
        });
    }
    indicesToSplice = [];
    gameFunctions.setTurns();
}

Your code is filled with IIFs that have no purpose. The gameFunctions.generateFlips function boils down to:

function generateFlips() {
    var flips = [];
    for (var i = 0; i < coinArrayLength; i++) {
        var currentFlip = Math.floor(Math.random() * (maxOdds - minOdds + 1)) + minOdds;
        flips.unshift(currentFlip);
    }
    return flips;
}

Yet you have it written with 2 return statements, inside an IIF, stored on a gameFunctions object. Keep it simple.

chrisbajorin
  • 5,993
  • 3
  • 21
  • 34