0

Background

I'm new to JavaScript and am solving various formulations of the Josephus Problem to better understand the syntax. Using a circularLinkedList implementation*, I've solved the classic formulation: Wikipedia||Numberphile. I've also solved the problem for any fixed number of fighters and a fixed number of skips between eliminations (e.g., if skipping two fighters between eliminations, 1 eliminates 4, 5 eliminates 8, etc). I am now trying to solve the problem given any function that indicates the number of skips at a given moment.

Problem

I can't access the return value of my skip function. I understand from 1, 2, 3 that my issue involves asynchronicity, but am having trouble isolating takeaways from the long responses involving AJAX and jQuery, which I'm unfamiliar with. Could I get an ELI5 solution? I apologize for my lack of understanding.

Code

    function winnerStepFunc(num, func) {
        let cll = new circularLinkedList(); //Initializing list with participants
        for (let a = 0; a < num; a++) {
            cll.append(a);
        }
        function next(funcSteps) { //Generating string indicating #steps from function's output 
            let toEvaluate = "start";
            for (let i = 0; i < funcSteps; i++) {
                toEvaluate += ".next"
            }
            return toEvaluate; 
        }
        let start = cll.getHead(); //Selecting first eliminator 
        while (cll.size() > 1) {
            let toCheck = func();                                     // PROBLEM LINE 
            console.log("toCheck = " + toCheck);                      //toCheck = undefined
            let str = next(toCheck);
            while (eval(str) !== start  && cll.size() > 1) { //
                let locCurrent = cll.indexOf(start.element);
                start = eval(str).next;
                cll.removeAt(((locCurrent + toCheck)% cll.size()));
            }
            cll.delete(eval(str).next.element);
            start = start.next;
        }
        console.log(start.element + 1);
    }
    
    function callFunction(name, args) {                // builds function string to be evaluated
        let result = name + "(";
        for (let i = 0; i < args.length -1; i++) {
            result += args[i] + ", ";
        }
        result += args[args.length-1] + ")";
        return result;
    }
    function callFunction(name) {
        let result = `${name}()`;
        return result;
    }
    function addOne() {                             //<--The first basic example I'm trying:
        return ++globalTimes;                       //Make the step increase by one for each elimination
    }
    var globalTimes = 0;
    winnerStepFunc(12, function(){eval(callFunction("addOne"))});

*CLL Implementation

  • Why not call it like `winnerStepFunc(12, function(){ return addOne()});`? Do you need the eval? Also dont forget to return in the function passed to `winnerStepFunc`. – Paul Rooney Feb 01 '21 at 01:50
  • 1
    Hi @PaulRooney. I agree that I don't need the function that itself creates the string for another function; I'm not sure why I thought that would add functionality. Your suggested change fixed the code! The only other thing I needed was to change the inner while loop to an if loop. Thank you! – CosmicNewt Feb 01 '21 at 02:03
  • I made it an answer. Let me know if it has any issues. – Paul Rooney Feb 01 '21 at 23:55

1 Answers1

0

You don't return in your function. I would remove all the eval stuff and just call the function directly.

winnerStepFunc(12, addOne);
Paul Rooney
  • 20,879
  • 9
  • 40
  • 61