Project Euler 7: 10001 Prime in Functional Programming (FP)

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












I wanted to practice functional programming (fp) without using any library but using vanilla JS only. So I took a problem from Project Euler:




By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can
see that the 6th prime is 13.



What is the 10 001st prime number?




This is my solution:



(function () 
'use strict';

function* checkForPrime(n)
let m = Math.floor(Math.sqrt(n) + 1);
while (true) n === 2


const isPrime = n => checkForPrime(n)
.next();

function* searchForPrimeNumbers(max)
let primeCounter = 0;
let newPrimeNumber = 1;
let runningNumber = 1;
while (true)
if (primeCounter === max)
yield newPrimeNumber;
return newPrimeNumber;

if (isPrime(runningNumber)
.value)
newPrimeNumber = runningNumber;
primeCounter = primeCounter + 1;

runningNumber++;



const finalsolution = searchForPrimeNumbers(1e4 + 1);

const findPrimeTill10001 = () =>
return finalsolution.next()
.value ? finalsolution.next()
.value : findPrimeTill10001();
;

const solution = findPrimeTill10001();
console.log(solution);
)();


As you can see, it is not consistent with the idea of FP. First I wanted to write it using recursion but I hit the stack limit. Therefore I used generators (and loops). That was the only solution I could come up with that resembles FP.



Any suggestions how to write in FP without any additional FP-Library (i.e. in pure JS only) is much appreciated.







share|improve this question



















  • Huh, why both yield newPrimeNumber; and return newPrimeNumber; ?
    – Igor Soloydenko
    Jan 4 at 21:17
















up vote
1
down vote

favorite












I wanted to practice functional programming (fp) without using any library but using vanilla JS only. So I took a problem from Project Euler:




By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can
see that the 6th prime is 13.



What is the 10 001st prime number?




This is my solution:



(function () 
'use strict';

function* checkForPrime(n)
let m = Math.floor(Math.sqrt(n) + 1);
while (true) n === 2


const isPrime = n => checkForPrime(n)
.next();

function* searchForPrimeNumbers(max)
let primeCounter = 0;
let newPrimeNumber = 1;
let runningNumber = 1;
while (true)
if (primeCounter === max)
yield newPrimeNumber;
return newPrimeNumber;

if (isPrime(runningNumber)
.value)
newPrimeNumber = runningNumber;
primeCounter = primeCounter + 1;

runningNumber++;



const finalsolution = searchForPrimeNumbers(1e4 + 1);

const findPrimeTill10001 = () =>
return finalsolution.next()
.value ? finalsolution.next()
.value : findPrimeTill10001();
;

const solution = findPrimeTill10001();
console.log(solution);
)();


As you can see, it is not consistent with the idea of FP. First I wanted to write it using recursion but I hit the stack limit. Therefore I used generators (and loops). That was the only solution I could come up with that resembles FP.



Any suggestions how to write in FP without any additional FP-Library (i.e. in pure JS only) is much appreciated.







share|improve this question



















  • Huh, why both yield newPrimeNumber; and return newPrimeNumber; ?
    – Igor Soloydenko
    Jan 4 at 21:17












up vote
1
down vote

favorite









up vote
1
down vote

favorite











I wanted to practice functional programming (fp) without using any library but using vanilla JS only. So I took a problem from Project Euler:




By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can
see that the 6th prime is 13.



What is the 10 001st prime number?




This is my solution:



(function () 
'use strict';

function* checkForPrime(n)
let m = Math.floor(Math.sqrt(n) + 1);
while (true) n === 2


const isPrime = n => checkForPrime(n)
.next();

function* searchForPrimeNumbers(max)
let primeCounter = 0;
let newPrimeNumber = 1;
let runningNumber = 1;
while (true)
if (primeCounter === max)
yield newPrimeNumber;
return newPrimeNumber;

if (isPrime(runningNumber)
.value)
newPrimeNumber = runningNumber;
primeCounter = primeCounter + 1;

runningNumber++;



const finalsolution = searchForPrimeNumbers(1e4 + 1);

const findPrimeTill10001 = () =>
return finalsolution.next()
.value ? finalsolution.next()
.value : findPrimeTill10001();
;

const solution = findPrimeTill10001();
console.log(solution);
)();


As you can see, it is not consistent with the idea of FP. First I wanted to write it using recursion but I hit the stack limit. Therefore I used generators (and loops). That was the only solution I could come up with that resembles FP.



Any suggestions how to write in FP without any additional FP-Library (i.e. in pure JS only) is much appreciated.







share|improve this question











I wanted to practice functional programming (fp) without using any library but using vanilla JS only. So I took a problem from Project Euler:




By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can
see that the 6th prime is 13.



What is the 10 001st prime number?




This is my solution:



(function () 
'use strict';

function* checkForPrime(n)
let m = Math.floor(Math.sqrt(n) + 1);
while (true) n === 2


const isPrime = n => checkForPrime(n)
.next();

function* searchForPrimeNumbers(max)
let primeCounter = 0;
let newPrimeNumber = 1;
let runningNumber = 1;
while (true)
if (primeCounter === max)
yield newPrimeNumber;
return newPrimeNumber;

if (isPrime(runningNumber)
.value)
newPrimeNumber = runningNumber;
primeCounter = primeCounter + 1;

runningNumber++;



const finalsolution = searchForPrimeNumbers(1e4 + 1);

const findPrimeTill10001 = () =>
return finalsolution.next()
.value ? finalsolution.next()
.value : findPrimeTill10001();
;

const solution = findPrimeTill10001();
console.log(solution);
)();


As you can see, it is not consistent with the idea of FP. First I wanted to write it using recursion but I hit the stack limit. Therefore I used generators (and loops). That was the only solution I could come up with that resembles FP.



Any suggestions how to write in FP without any additional FP-Library (i.e. in pure JS only) is much appreciated.









share|improve this question










share|improve this question




share|improve this question









asked Jan 4 at 20:47









thadeuszlay

435212




435212











  • Huh, why both yield newPrimeNumber; and return newPrimeNumber; ?
    – Igor Soloydenko
    Jan 4 at 21:17
















  • Huh, why both yield newPrimeNumber; and return newPrimeNumber; ?
    – Igor Soloydenko
    Jan 4 at 21:17















Huh, why both yield newPrimeNumber; and return newPrimeNumber; ?
– Igor Soloydenko
Jan 4 at 21:17




Huh, why both yield newPrimeNumber; and return newPrimeNumber; ?
– Igor Soloydenko
Jan 4 at 21:17










2 Answers
2






active

oldest

votes

















up vote
2
down vote



accepted










You shouldn't be doing things in a loop that don't depend on things changing in the loop. n < 2, n === 2, and n === 3 all depend on n, which is constant throughout your loop. Also, if you store your primes, you just have to loop through the primes until you get to sqrt(n), rather than checking every number. There are further tricks to speed up the algorithm, such as checking n only if n mod 60 is in [7,11,13,17,23,29,31,37,41,43,47,49,53,59]; that reduces the number of n to check by more than 3/4.



Is tail recursion an option?



How large is your stack size? You can break recursion into subrecursion. For instance, suppose you have a function that recursively finds the nth to n+100th primes. Then you can have a recursive function than, when asked to find k primes, calls itself on k-101, then appends the k-100 to kth primes. You can then add another layer, and have something that does 10 primes at a time. Do this in binary rather than base 10, and you'll need 14 layers to get 10001 primes.






share|improve this answer




























    up vote
    2
    down vote













    Seems like you've figured this out yourself already, but I'll state it for you to make it clear...



    The idea behind functional programming is mainly to make things easier to read and maintain (by being "declarative"). Usually/often this is done at the expense of performance. For example, it's a whole lot faster to iterate thru an array with a for loop than with the forEach method. Project Euler (or anything involving large numbers or heavy processing) is probably not a good place to practice functional programming with Javascript.



    That said, this problem in particular doesn't justify the use of more than one function anyway. Your algorithm is overly complicated.






    function getNthPrime(n) 
    let primes = [2, 3, 5];
    const isPrime = num =>
    for (let n = 0; n < primes.length; n++)
    if (num === primes[n]) return true;
    if (num % primes[n] === 0) return false;

    return true;
    ;
    for (var i = 3; primes.length < n; i++)
    if (isPrime(i) && primes.indexOf(i) === -1) primes.push(i);
    return primes.pop();
    ;

    console.log(getNthPrime(10001));





    Now, if you really wanna do complicated math stuff functionally, I suggest making your own library, that way you get the benefit of learning how to do it with "vanilla" JS and you get to use the functional approach at the same time. That's what I'm doing.






    share|improve this answer





















    • Cool project. And thanks for the suggestion. Though, I'd really be interested in a pure FP solution for this problem. If you know one, then let me know.
      – thadeuszlay
      Jan 6 at 15:57










    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184312%2fproject-euler-7-10001-prime-in-functional-programming-fp%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote



    accepted










    You shouldn't be doing things in a loop that don't depend on things changing in the loop. n < 2, n === 2, and n === 3 all depend on n, which is constant throughout your loop. Also, if you store your primes, you just have to loop through the primes until you get to sqrt(n), rather than checking every number. There are further tricks to speed up the algorithm, such as checking n only if n mod 60 is in [7,11,13,17,23,29,31,37,41,43,47,49,53,59]; that reduces the number of n to check by more than 3/4.



    Is tail recursion an option?



    How large is your stack size? You can break recursion into subrecursion. For instance, suppose you have a function that recursively finds the nth to n+100th primes. Then you can have a recursive function than, when asked to find k primes, calls itself on k-101, then appends the k-100 to kth primes. You can then add another layer, and have something that does 10 primes at a time. Do this in binary rather than base 10, and you'll need 14 layers to get 10001 primes.






    share|improve this answer

























      up vote
      2
      down vote



      accepted










      You shouldn't be doing things in a loop that don't depend on things changing in the loop. n < 2, n === 2, and n === 3 all depend on n, which is constant throughout your loop. Also, if you store your primes, you just have to loop through the primes until you get to sqrt(n), rather than checking every number. There are further tricks to speed up the algorithm, such as checking n only if n mod 60 is in [7,11,13,17,23,29,31,37,41,43,47,49,53,59]; that reduces the number of n to check by more than 3/4.



      Is tail recursion an option?



      How large is your stack size? You can break recursion into subrecursion. For instance, suppose you have a function that recursively finds the nth to n+100th primes. Then you can have a recursive function than, when asked to find k primes, calls itself on k-101, then appends the k-100 to kth primes. You can then add another layer, and have something that does 10 primes at a time. Do this in binary rather than base 10, and you'll need 14 layers to get 10001 primes.






      share|improve this answer























        up vote
        2
        down vote



        accepted







        up vote
        2
        down vote



        accepted






        You shouldn't be doing things in a loop that don't depend on things changing in the loop. n < 2, n === 2, and n === 3 all depend on n, which is constant throughout your loop. Also, if you store your primes, you just have to loop through the primes until you get to sqrt(n), rather than checking every number. There are further tricks to speed up the algorithm, such as checking n only if n mod 60 is in [7,11,13,17,23,29,31,37,41,43,47,49,53,59]; that reduces the number of n to check by more than 3/4.



        Is tail recursion an option?



        How large is your stack size? You can break recursion into subrecursion. For instance, suppose you have a function that recursively finds the nth to n+100th primes. Then you can have a recursive function than, when asked to find k primes, calls itself on k-101, then appends the k-100 to kth primes. You can then add another layer, and have something that does 10 primes at a time. Do this in binary rather than base 10, and you'll need 14 layers to get 10001 primes.






        share|improve this answer













        You shouldn't be doing things in a loop that don't depend on things changing in the loop. n < 2, n === 2, and n === 3 all depend on n, which is constant throughout your loop. Also, if you store your primes, you just have to loop through the primes until you get to sqrt(n), rather than checking every number. There are further tricks to speed up the algorithm, such as checking n only if n mod 60 is in [7,11,13,17,23,29,31,37,41,43,47,49,53,59]; that reduces the number of n to check by more than 3/4.



        Is tail recursion an option?



        How large is your stack size? You can break recursion into subrecursion. For instance, suppose you have a function that recursively finds the nth to n+100th primes. Then you can have a recursive function than, when asked to find k primes, calls itself on k-101, then appends the k-100 to kth primes. You can then add another layer, and have something that does 10 primes at a time. Do this in binary rather than base 10, and you'll need 14 layers to get 10001 primes.







        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered Jan 4 at 21:20









        Acccumulation

        1,0195




        1,0195






















            up vote
            2
            down vote













            Seems like you've figured this out yourself already, but I'll state it for you to make it clear...



            The idea behind functional programming is mainly to make things easier to read and maintain (by being "declarative"). Usually/often this is done at the expense of performance. For example, it's a whole lot faster to iterate thru an array with a for loop than with the forEach method. Project Euler (or anything involving large numbers or heavy processing) is probably not a good place to practice functional programming with Javascript.



            That said, this problem in particular doesn't justify the use of more than one function anyway. Your algorithm is overly complicated.






            function getNthPrime(n) 
            let primes = [2, 3, 5];
            const isPrime = num =>
            for (let n = 0; n < primes.length; n++)
            if (num === primes[n]) return true;
            if (num % primes[n] === 0) return false;

            return true;
            ;
            for (var i = 3; primes.length < n; i++)
            if (isPrime(i) && primes.indexOf(i) === -1) primes.push(i);
            return primes.pop();
            ;

            console.log(getNthPrime(10001));





            Now, if you really wanna do complicated math stuff functionally, I suggest making your own library, that way you get the benefit of learning how to do it with "vanilla" JS and you get to use the functional approach at the same time. That's what I'm doing.






            share|improve this answer





















            • Cool project. And thanks for the suggestion. Though, I'd really be interested in a pure FP solution for this problem. If you know one, then let me know.
              – thadeuszlay
              Jan 6 at 15:57














            up vote
            2
            down vote













            Seems like you've figured this out yourself already, but I'll state it for you to make it clear...



            The idea behind functional programming is mainly to make things easier to read and maintain (by being "declarative"). Usually/often this is done at the expense of performance. For example, it's a whole lot faster to iterate thru an array with a for loop than with the forEach method. Project Euler (or anything involving large numbers or heavy processing) is probably not a good place to practice functional programming with Javascript.



            That said, this problem in particular doesn't justify the use of more than one function anyway. Your algorithm is overly complicated.






            function getNthPrime(n) 
            let primes = [2, 3, 5];
            const isPrime = num =>
            for (let n = 0; n < primes.length; n++)
            if (num === primes[n]) return true;
            if (num % primes[n] === 0) return false;

            return true;
            ;
            for (var i = 3; primes.length < n; i++)
            if (isPrime(i) && primes.indexOf(i) === -1) primes.push(i);
            return primes.pop();
            ;

            console.log(getNthPrime(10001));





            Now, if you really wanna do complicated math stuff functionally, I suggest making your own library, that way you get the benefit of learning how to do it with "vanilla" JS and you get to use the functional approach at the same time. That's what I'm doing.






            share|improve this answer





















            • Cool project. And thanks for the suggestion. Though, I'd really be interested in a pure FP solution for this problem. If you know one, then let me know.
              – thadeuszlay
              Jan 6 at 15:57












            up vote
            2
            down vote










            up vote
            2
            down vote









            Seems like you've figured this out yourself already, but I'll state it for you to make it clear...



            The idea behind functional programming is mainly to make things easier to read and maintain (by being "declarative"). Usually/often this is done at the expense of performance. For example, it's a whole lot faster to iterate thru an array with a for loop than with the forEach method. Project Euler (or anything involving large numbers or heavy processing) is probably not a good place to practice functional programming with Javascript.



            That said, this problem in particular doesn't justify the use of more than one function anyway. Your algorithm is overly complicated.






            function getNthPrime(n) 
            let primes = [2, 3, 5];
            const isPrime = num =>
            for (let n = 0; n < primes.length; n++)
            if (num === primes[n]) return true;
            if (num % primes[n] === 0) return false;

            return true;
            ;
            for (var i = 3; primes.length < n; i++)
            if (isPrime(i) && primes.indexOf(i) === -1) primes.push(i);
            return primes.pop();
            ;

            console.log(getNthPrime(10001));





            Now, if you really wanna do complicated math stuff functionally, I suggest making your own library, that way you get the benefit of learning how to do it with "vanilla" JS and you get to use the functional approach at the same time. That's what I'm doing.






            share|improve this answer













            Seems like you've figured this out yourself already, but I'll state it for you to make it clear...



            The idea behind functional programming is mainly to make things easier to read and maintain (by being "declarative"). Usually/often this is done at the expense of performance. For example, it's a whole lot faster to iterate thru an array with a for loop than with the forEach method. Project Euler (or anything involving large numbers or heavy processing) is probably not a good place to practice functional programming with Javascript.



            That said, this problem in particular doesn't justify the use of more than one function anyway. Your algorithm is overly complicated.






            function getNthPrime(n) 
            let primes = [2, 3, 5];
            const isPrime = num =>
            for (let n = 0; n < primes.length; n++)
            if (num === primes[n]) return true;
            if (num % primes[n] === 0) return false;

            return true;
            ;
            for (var i = 3; primes.length < n; i++)
            if (isPrime(i) && primes.indexOf(i) === -1) primes.push(i);
            return primes.pop();
            ;

            console.log(getNthPrime(10001));





            Now, if you really wanna do complicated math stuff functionally, I suggest making your own library, that way you get the benefit of learning how to do it with "vanilla" JS and you get to use the functional approach at the same time. That's what I'm doing.






            function getNthPrime(n) 
            let primes = [2, 3, 5];
            const isPrime = num =>
            for (let n = 0; n < primes.length; n++)
            if (num === primes[n]) return true;
            if (num % primes[n] === 0) return false;

            return true;
            ;
            for (var i = 3; primes.length < n; i++)
            if (isPrime(i) && primes.indexOf(i) === -1) primes.push(i);
            return primes.pop();
            ;

            console.log(getNthPrime(10001));





            function getNthPrime(n) 
            let primes = [2, 3, 5];
            const isPrime = num =>
            for (let n = 0; n < primes.length; n++)
            if (num === primes[n]) return true;
            if (num % primes[n] === 0) return false;

            return true;
            ;
            for (var i = 3; primes.length < n; i++)
            if (isPrime(i) && primes.indexOf(i) === -1) primes.push(i);
            return primes.pop();
            ;

            console.log(getNthPrime(10001));






            share|improve this answer













            share|improve this answer



            share|improve this answer











            answered Jan 5 at 16:50









            Occam's Razor

            1,982513




            1,982513











            • Cool project. And thanks for the suggestion. Though, I'd really be interested in a pure FP solution for this problem. If you know one, then let me know.
              – thadeuszlay
              Jan 6 at 15:57
















            • Cool project. And thanks for the suggestion. Though, I'd really be interested in a pure FP solution for this problem. If you know one, then let me know.
              – thadeuszlay
              Jan 6 at 15:57















            Cool project. And thanks for the suggestion. Though, I'd really be interested in a pure FP solution for this problem. If you know one, then let me know.
            – thadeuszlay
            Jan 6 at 15:57




            Cool project. And thanks for the suggestion. Though, I'd really be interested in a pure FP solution for this problem. If you know one, then let me know.
            – thadeuszlay
            Jan 6 at 15:57












             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184312%2fproject-euler-7-10001-prime-in-functional-programming-fp%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Greedy Best First Search implementation in Rust

            Function to Return a JSON Like Objects Using VBA Collections and Arrays

            C++11 CLH Lock Implementation