views:

637

answers:

3
projectEuler3(600851475143);

var projectEuler3 = function (composite) {
    var result = 2;
    while(composite > 1)
    {
        if (composite % result)
        {
            result++
        } else {
            composite = composite / result;
            console.log(result);
        }
    }
};
+3  A: 

EDIT: Turns out this question is designed to be a how to change an algorithm (in general) from iterative to recursive...not, as I assumed, how to get an answer to a particular problem.

This is for Project Euler! Project Euler is purely for your own benefit...if you're going to have someone else do the work for you, you could probably just look up the answer on google somewhere and type it in.

I can only guess you've decided that your program is correct, but that it is too slow, and you're hoping to speed it up. Making your function recursive won't help.

The site points out that if your program doesn't solve the question quickly, there's a better approach...try a different tact.

Beska
Recursion is *definitely* not the first place to look to in speeding up code... Lol - +1
Erik Forbes
yes it's from project euler. that's why i tagged it as such. but no, i am not trying to speed it up. run it, it's very fast. i want to make my brain think recursively and this is helpful to that end.
shawndumas
@ShawnDumas...okay, that makes sense! (I'm glad I didn't jump on the bandwagon to ding the question!) Next time, give a bit more information to hopefully keep the dings away. Check out Ben Blank's response...he's got a generic template you might be able to apply.
Beska
it was definitely a case of me not being clear!
shawndumas
+2  A: 

Hopefully in the spirit both of Project Euler (learn-by-doing) and SO (learn-by-asking), here's a fairly generic template for making a loop into tail-call recursion:

var projectEuler3 = function(n) {
    var pE3_inner = function(n, i) {
        // magic happens here

        // if neither n nor i has changed, this is an
        // infinite recursion (and usually a stack overflow)
        pE3_inner(n, i);
    }

    pE3_inner(n, 2);
}
Ben Blank
var pe3 = function (o) { o = o || { composite: 600851475143, result: 2 }; if (o.composite < 1) return o.result; (o.composite % o.result) ? o.result++ : o.composite = o.composite / o.result; return pe3(o);};pe3();this is getting me an InternalError: too much recursion...
shawndumas
Yep! That's one of the big drawbacks to recursion...it can generate a lot of stack. Still, that shouldn't matter in your case. Just pick a smaller number that will work, so that you can verify your code is doing what you expect.
Beska
even 10 is giving me that...
shawndumas
Try changing your "< 1" to "< 2". At some point, o.composite and o.result will be the same and o.composite will be changed to 1. It will never be divided again, however, so it will never drop below one (barring rounding errors) and your function will overflow the stack.
Ben Blank
i think the object sucks so i used a closure:var pe3 = function (composite) { var result = 2; return (function () { if (composite <= 1) return result; (composite % result) ? result++ : composite = composite / result; return arguments.callee(result); })();};
shawndumas
...that works up till 9999995. any bigger and it blows...
shawndumas
+2  A: 

Structure and Interpretation of Computer Programs introduces the difference between iterative and recursive algorithms, how to identify which is which (in some languages it's not so obvious!), and how to convert from one to the other.

In addition to being an excellent textbook.

Greg Hewgill