Relative prime numbers












3














Two integers a and b are relatively prime if and only if there are no integers:




x > 1, y > 0, z > 0 such that a = xy and b = xz.




I wrote a program that determines how many positive integers less than n are relatively prime to n. But my program works too slowly because the number is sometimes too big.



My program should work for n <= 1000000000.



#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
long long int n;
int cntr = 0, cntr2 = 0;
cin >> n;
if (!n) return 0;
vector <int> num;
for (int i = 2; i < n; i++)
{
if (n % i != 0)
{
if (num.size()>0)
{
for (int j = 0; j < num.size(); j++)
{
if (i % num[j] != 0)
cntr2++;
}
if (cntr2 == num.size())
cntr++;
cntr2 = 0;
}
else
cntr++;
}
else
num.push_back(i);
}
cout << cntr + 1 << endl;
}









share|improve this question





























    3














    Two integers a and b are relatively prime if and only if there are no integers:




    x > 1, y > 0, z > 0 such that a = xy and b = xz.




    I wrote a program that determines how many positive integers less than n are relatively prime to n. But my program works too slowly because the number is sometimes too big.



    My program should work for n <= 1000000000.



    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;

    int main()
    {
    long long int n;
    int cntr = 0, cntr2 = 0;
    cin >> n;
    if (!n) return 0;
    vector <int> num;
    for (int i = 2; i < n; i++)
    {
    if (n % i != 0)
    {
    if (num.size()>0)
    {
    for (int j = 0; j < num.size(); j++)
    {
    if (i % num[j] != 0)
    cntr2++;
    }
    if (cntr2 == num.size())
    cntr++;
    cntr2 = 0;
    }
    else
    cntr++;
    }
    else
    num.push_back(i);
    }
    cout << cntr + 1 << endl;
    }









    share|improve this question



























      3












      3








      3







      Two integers a and b are relatively prime if and only if there are no integers:




      x > 1, y > 0, z > 0 such that a = xy and b = xz.




      I wrote a program that determines how many positive integers less than n are relatively prime to n. But my program works too slowly because the number is sometimes too big.



      My program should work for n <= 1000000000.



      #include <iostream>
      #include <vector>
      #include <algorithm>
      using namespace std;

      int main()
      {
      long long int n;
      int cntr = 0, cntr2 = 0;
      cin >> n;
      if (!n) return 0;
      vector <int> num;
      for (int i = 2; i < n; i++)
      {
      if (n % i != 0)
      {
      if (num.size()>0)
      {
      for (int j = 0; j < num.size(); j++)
      {
      if (i % num[j] != 0)
      cntr2++;
      }
      if (cntr2 == num.size())
      cntr++;
      cntr2 = 0;
      }
      else
      cntr++;
      }
      else
      num.push_back(i);
      }
      cout << cntr + 1 << endl;
      }









      share|improve this question















      Two integers a and b are relatively prime if and only if there are no integers:




      x > 1, y > 0, z > 0 such that a = xy and b = xz.




      I wrote a program that determines how many positive integers less than n are relatively prime to n. But my program works too slowly because the number is sometimes too big.



      My program should work for n <= 1000000000.



      #include <iostream>
      #include <vector>
      #include <algorithm>
      using namespace std;

      int main()
      {
      long long int n;
      int cntr = 0, cntr2 = 0;
      cin >> n;
      if (!n) return 0;
      vector <int> num;
      for (int i = 2; i < n; i++)
      {
      if (n % i != 0)
      {
      if (num.size()>0)
      {
      for (int j = 0; j < num.size(); j++)
      {
      if (i % num[j] != 0)
      cntr2++;
      }
      if (cntr2 == num.size())
      cntr++;
      cntr2 = 0;
      }
      else
      cntr++;
      }
      else
      num.push_back(i);
      }
      cout << cntr + 1 << endl;
      }






      c++ performance primes






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 12 '14 at 23:34









      Jamal

      30.3k11116226




      30.3k11116226










      asked Jan 12 '14 at 23:31









      DanialV

      1612




      1612






















          5 Answers
          5






          active

          oldest

          votes


















          5














          In order to determine whether two numbers are co-prime (relatively prime), you can check whether their gcd (greatest common divisor) is greater than 1.
          The gcd can be calculated by Euclid's algorithm:



          unsigned int gcd (unsigned int a, unsigned int b)
          {
          unsigned int x;
          while (b)
          {
          x = a % b;
          a = b;
          b = x;
          }
          return a;
          }


          if gcd(x,y) > 1: the numbers are not co-prime.



          If the code is supposed to run on a platform with slow integer division, you can use the so called binary gcd instead.






          share|improve this answer























          • Original sultion might be a bit better because it takes into account the fact that we need to find set of co-primes rather than check one particular pair.
            – ony
            Jan 13 '14 at 9:19





















          0














          Your code can be simplified by eliminating a special case. This…



          if (n % i != 0)
          {
          if (num.size()>0)
          {
          for (int j = 0; j < num.size(); j++)
          {
          if (i % num[j] != 0)
          cntr2++;
          }
          if (cntr2 == num.size())
          cntr++;
          cntr2 = 0;
          }
          else
          cntr++;
          }


          … can be written as:



          if (n % i != 0)
          {
          int cntr2 = 0;
          for (int j = 0; j < num.size(); j++)
          {
          if (i % num[j] != 0)
          cntr2++;
          }
          if (cntr2 == num.size())
          cntr++;
          }


          Furthermore, you could eliminate cntr2. Breaking from the loop earlier saves work and should improve performance.



          if (n % i != 0)
          {
          for (int j = 0; j < num.size(); j++)
          {
          if (i % num[j] == 0)
          {
          cntr--;
          break;
          }
          }
          cntr++;
          }





          share|improve this answer























          • Didn't you've lost populating num vector?
            – ony
            Jan 13 '14 at 8:15










          • @ony I took the wrong excerpt. Thanks!
            – 200_success
            Jan 13 '14 at 8:27



















          0














          Suggestions from @200_success will bring you speedup like from ~28.1s to ~11.8s (gcc 4.8.2 with -O3).
          Replacing all with gcd as suggested @EOF will give you ~11.4s and will save some memory.



          Overall idea is somewhat correct. You collect factors of n and check that there is no factors within other numbers (that are not already factors of n).



          But I guess you can improve solution by factoring with primes and avoid populating num with numbers like 4, 6, 8, 9 etc. That brings time to ~1.3s.



          for (int i = 2; i < n; i++)
          {
          if (n % i == 0)
          {
          bool foundFactor = false;
          for (int j = 0; j < num.size(); ++j)
          {
          if (i % num[j] == 0)
          {
          foundFactor = true;
          break;
          }
          }
          if (!foundFactor) num.push_back(i);
          continue;
          }
          bool foundFactor = false;
          for (int j = 0; j < num.size(); ++j)
          {
          if (i % num[j] == 0)
          {
          foundFactor = true;
          break;
          }
          }
          if (!foundFactor)
          cntr++;
          }


          For your n = 1000000000 I've got ~13.6s



          Note that there is a linear relation beetween numbers of co-primes in 1000000000 and 1000. That's because the only difference between them is (2*5)**k. That leads us to another optimization based on the wheel factorization:



          long long wheel = 1;

          // factorization of n
          for (long long i = 2, m = n; i <= m; i++)
          {
          if (m % i == 0)
          {
          num.push_back(i);
          wheel *= i; // re-size wheel
          // remove powers of i from m
          do { m /= i; } while (m % i == 0);
          }
          }

          for (int i = 2; i < wheel; i++)
          {
          if (n % i == 0)
          {
          continue;
          }
          bool foundFactor = false;
          for (int j = 0; j < num.size() && num[j] < i; ++j)
          {
          if (i % num[j] == 0)
          {
          foundFactor = true;
          break;
          }
          }
          if (!foundFactor)
          cntr++;
          }
          cout << cntr+1 << endl;
          cout << (cntr+1)*n/wheel << endl;


          That gives ~0s for almost any 10**k



          P.S. It sound pretty much as Project Euler problem I've met once. I used a bit different approach. I already had a pretty good framework for working with primes and I just simply generated all numbers out of primes that have no factors of n initially. I.e. built up sequence of combinations 3**k * 7**k ... until they've reached n.






          share|improve this answer































            0














            I don't know if you still need this, since it is a very old question. I wrote it for anybody else who might be looking for the answer.



            This counts every N's "relatively prime number" (less then N). It is called Eulers' totient function.



            #include <cstdio>
            typedef long long lld;

            lld f(lld num)
            {
            lld ans = num;
            for (lld i = 2; i*i <= num; i++)
            {
            if (num%i==0)
            {
            while (num%i==0) num /= i;
            ans -= ans / i;
            }
            }
            if (num > 1)
            ans -= ans / num;
            return ans;
            }

            int main()
            {
            lld N;
            scanf("%lld", &N);
            printf("%lld", f(N));
            }





            share|improve this answer























            • Euler's totient function
              – Gs_
              Jun 7 '17 at 13:16






            • 2




              This is basically a code dump answer (even after moving the explanatory text to the top). Every answer must make at least one insightful observation about the code in the question and not just offer an alternative implementation without at least explaining what it does better or how. See the help-center for more information.
              – Graipher
              Jun 7 '17 at 13:36





















            0














            Gs_'s answer starts off by essentially finding all the prime factors of n. If you're going to do that, then you might as well use the following well-known formula that calculates the Euler function from the prime factorisation:



            phi(p1 ^ a1 * ... * pk ^ ak) =
            (p1 ^ a1 - p1 ^ (a1 - 1))
            * ...
            * (pk ^ ak - pk ^ (ak - 1))


            The code would look something like this:



            long long phi = 1;

            // factorization of n
            for (long long i = 2, m = n; m > 1; i++)
            {
            // Now phi(n/m) == phi
            if (m % i == 0)
            {
            // i is the smallest prime factor of m, and is not a factor of n/m
            m /= i;
            phi *= (i - 1);
            while (m % i == 0) {
            m /= i;
            phi *= i;
            }
            }
            }

            return phi;





            share|improve this answer























            • What's wheel?
              – 200_success
              Jan 13 '14 at 12:07










            • @200_success That was in ony's code. I forgot to delete it. It's removed now. Thanks.
              – David Knipe
              Jan 13 '14 at 12:34











            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',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            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%2f39109%2frelative-prime-numbers%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            5 Answers
            5






            active

            oldest

            votes








            5 Answers
            5






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            5














            In order to determine whether two numbers are co-prime (relatively prime), you can check whether their gcd (greatest common divisor) is greater than 1.
            The gcd can be calculated by Euclid's algorithm:



            unsigned int gcd (unsigned int a, unsigned int b)
            {
            unsigned int x;
            while (b)
            {
            x = a % b;
            a = b;
            b = x;
            }
            return a;
            }


            if gcd(x,y) > 1: the numbers are not co-prime.



            If the code is supposed to run on a platform with slow integer division, you can use the so called binary gcd instead.






            share|improve this answer























            • Original sultion might be a bit better because it takes into account the fact that we need to find set of co-primes rather than check one particular pair.
              – ony
              Jan 13 '14 at 9:19


















            5














            In order to determine whether two numbers are co-prime (relatively prime), you can check whether their gcd (greatest common divisor) is greater than 1.
            The gcd can be calculated by Euclid's algorithm:



            unsigned int gcd (unsigned int a, unsigned int b)
            {
            unsigned int x;
            while (b)
            {
            x = a % b;
            a = b;
            b = x;
            }
            return a;
            }


            if gcd(x,y) > 1: the numbers are not co-prime.



            If the code is supposed to run on a platform with slow integer division, you can use the so called binary gcd instead.






            share|improve this answer























            • Original sultion might be a bit better because it takes into account the fact that we need to find set of co-primes rather than check one particular pair.
              – ony
              Jan 13 '14 at 9:19
















            5












            5








            5






            In order to determine whether two numbers are co-prime (relatively prime), you can check whether their gcd (greatest common divisor) is greater than 1.
            The gcd can be calculated by Euclid's algorithm:



            unsigned int gcd (unsigned int a, unsigned int b)
            {
            unsigned int x;
            while (b)
            {
            x = a % b;
            a = b;
            b = x;
            }
            return a;
            }


            if gcd(x,y) > 1: the numbers are not co-prime.



            If the code is supposed to run on a platform with slow integer division, you can use the so called binary gcd instead.






            share|improve this answer














            In order to determine whether two numbers are co-prime (relatively prime), you can check whether their gcd (greatest common divisor) is greater than 1.
            The gcd can be calculated by Euclid's algorithm:



            unsigned int gcd (unsigned int a, unsigned int b)
            {
            unsigned int x;
            while (b)
            {
            x = a % b;
            a = b;
            b = x;
            }
            return a;
            }


            if gcd(x,y) > 1: the numbers are not co-prime.



            If the code is supposed to run on a platform with slow integer division, you can use the so called binary gcd instead.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jan 13 '14 at 1:36









            izabera

            1734




            1734










            answered Jan 12 '14 at 23:54









            EOF

            31117




            31117












            • Original sultion might be a bit better because it takes into account the fact that we need to find set of co-primes rather than check one particular pair.
              – ony
              Jan 13 '14 at 9:19




















            • Original sultion might be a bit better because it takes into account the fact that we need to find set of co-primes rather than check one particular pair.
              – ony
              Jan 13 '14 at 9:19


















            Original sultion might be a bit better because it takes into account the fact that we need to find set of co-primes rather than check one particular pair.
            – ony
            Jan 13 '14 at 9:19






            Original sultion might be a bit better because it takes into account the fact that we need to find set of co-primes rather than check one particular pair.
            – ony
            Jan 13 '14 at 9:19















            0














            Your code can be simplified by eliminating a special case. This…



            if (n % i != 0)
            {
            if (num.size()>0)
            {
            for (int j = 0; j < num.size(); j++)
            {
            if (i % num[j] != 0)
            cntr2++;
            }
            if (cntr2 == num.size())
            cntr++;
            cntr2 = 0;
            }
            else
            cntr++;
            }


            … can be written as:



            if (n % i != 0)
            {
            int cntr2 = 0;
            for (int j = 0; j < num.size(); j++)
            {
            if (i % num[j] != 0)
            cntr2++;
            }
            if (cntr2 == num.size())
            cntr++;
            }


            Furthermore, you could eliminate cntr2. Breaking from the loop earlier saves work and should improve performance.



            if (n % i != 0)
            {
            for (int j = 0; j < num.size(); j++)
            {
            if (i % num[j] == 0)
            {
            cntr--;
            break;
            }
            }
            cntr++;
            }





            share|improve this answer























            • Didn't you've lost populating num vector?
              – ony
              Jan 13 '14 at 8:15










            • @ony I took the wrong excerpt. Thanks!
              – 200_success
              Jan 13 '14 at 8:27
















            0














            Your code can be simplified by eliminating a special case. This…



            if (n % i != 0)
            {
            if (num.size()>0)
            {
            for (int j = 0; j < num.size(); j++)
            {
            if (i % num[j] != 0)
            cntr2++;
            }
            if (cntr2 == num.size())
            cntr++;
            cntr2 = 0;
            }
            else
            cntr++;
            }


            … can be written as:



            if (n % i != 0)
            {
            int cntr2 = 0;
            for (int j = 0; j < num.size(); j++)
            {
            if (i % num[j] != 0)
            cntr2++;
            }
            if (cntr2 == num.size())
            cntr++;
            }


            Furthermore, you could eliminate cntr2. Breaking from the loop earlier saves work and should improve performance.



            if (n % i != 0)
            {
            for (int j = 0; j < num.size(); j++)
            {
            if (i % num[j] == 0)
            {
            cntr--;
            break;
            }
            }
            cntr++;
            }





            share|improve this answer























            • Didn't you've lost populating num vector?
              – ony
              Jan 13 '14 at 8:15










            • @ony I took the wrong excerpt. Thanks!
              – 200_success
              Jan 13 '14 at 8:27














            0












            0








            0






            Your code can be simplified by eliminating a special case. This…



            if (n % i != 0)
            {
            if (num.size()>0)
            {
            for (int j = 0; j < num.size(); j++)
            {
            if (i % num[j] != 0)
            cntr2++;
            }
            if (cntr2 == num.size())
            cntr++;
            cntr2 = 0;
            }
            else
            cntr++;
            }


            … can be written as:



            if (n % i != 0)
            {
            int cntr2 = 0;
            for (int j = 0; j < num.size(); j++)
            {
            if (i % num[j] != 0)
            cntr2++;
            }
            if (cntr2 == num.size())
            cntr++;
            }


            Furthermore, you could eliminate cntr2. Breaking from the loop earlier saves work and should improve performance.



            if (n % i != 0)
            {
            for (int j = 0; j < num.size(); j++)
            {
            if (i % num[j] == 0)
            {
            cntr--;
            break;
            }
            }
            cntr++;
            }





            share|improve this answer














            Your code can be simplified by eliminating a special case. This…



            if (n % i != 0)
            {
            if (num.size()>0)
            {
            for (int j = 0; j < num.size(); j++)
            {
            if (i % num[j] != 0)
            cntr2++;
            }
            if (cntr2 == num.size())
            cntr++;
            cntr2 = 0;
            }
            else
            cntr++;
            }


            … can be written as:



            if (n % i != 0)
            {
            int cntr2 = 0;
            for (int j = 0; j < num.size(); j++)
            {
            if (i % num[j] != 0)
            cntr2++;
            }
            if (cntr2 == num.size())
            cntr++;
            }


            Furthermore, you could eliminate cntr2. Breaking from the loop earlier saves work and should improve performance.



            if (n % i != 0)
            {
            for (int j = 0; j < num.size(); j++)
            {
            if (i % num[j] == 0)
            {
            cntr--;
            break;
            }
            }
            cntr++;
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jan 13 '14 at 8:27

























            answered Jan 13 '14 at 2:23









            200_success

            128k15152413




            128k15152413












            • Didn't you've lost populating num vector?
              – ony
              Jan 13 '14 at 8:15










            • @ony I took the wrong excerpt. Thanks!
              – 200_success
              Jan 13 '14 at 8:27


















            • Didn't you've lost populating num vector?
              – ony
              Jan 13 '14 at 8:15










            • @ony I took the wrong excerpt. Thanks!
              – 200_success
              Jan 13 '14 at 8:27
















            Didn't you've lost populating num vector?
            – ony
            Jan 13 '14 at 8:15




            Didn't you've lost populating num vector?
            – ony
            Jan 13 '14 at 8:15












            @ony I took the wrong excerpt. Thanks!
            – 200_success
            Jan 13 '14 at 8:27




            @ony I took the wrong excerpt. Thanks!
            – 200_success
            Jan 13 '14 at 8:27











            0














            Suggestions from @200_success will bring you speedup like from ~28.1s to ~11.8s (gcc 4.8.2 with -O3).
            Replacing all with gcd as suggested @EOF will give you ~11.4s and will save some memory.



            Overall idea is somewhat correct. You collect factors of n and check that there is no factors within other numbers (that are not already factors of n).



            But I guess you can improve solution by factoring with primes and avoid populating num with numbers like 4, 6, 8, 9 etc. That brings time to ~1.3s.



            for (int i = 2; i < n; i++)
            {
            if (n % i == 0)
            {
            bool foundFactor = false;
            for (int j = 0; j < num.size(); ++j)
            {
            if (i % num[j] == 0)
            {
            foundFactor = true;
            break;
            }
            }
            if (!foundFactor) num.push_back(i);
            continue;
            }
            bool foundFactor = false;
            for (int j = 0; j < num.size(); ++j)
            {
            if (i % num[j] == 0)
            {
            foundFactor = true;
            break;
            }
            }
            if (!foundFactor)
            cntr++;
            }


            For your n = 1000000000 I've got ~13.6s



            Note that there is a linear relation beetween numbers of co-primes in 1000000000 and 1000. That's because the only difference between them is (2*5)**k. That leads us to another optimization based on the wheel factorization:



            long long wheel = 1;

            // factorization of n
            for (long long i = 2, m = n; i <= m; i++)
            {
            if (m % i == 0)
            {
            num.push_back(i);
            wheel *= i; // re-size wheel
            // remove powers of i from m
            do { m /= i; } while (m % i == 0);
            }
            }

            for (int i = 2; i < wheel; i++)
            {
            if (n % i == 0)
            {
            continue;
            }
            bool foundFactor = false;
            for (int j = 0; j < num.size() && num[j] < i; ++j)
            {
            if (i % num[j] == 0)
            {
            foundFactor = true;
            break;
            }
            }
            if (!foundFactor)
            cntr++;
            }
            cout << cntr+1 << endl;
            cout << (cntr+1)*n/wheel << endl;


            That gives ~0s for almost any 10**k



            P.S. It sound pretty much as Project Euler problem I've met once. I used a bit different approach. I already had a pretty good framework for working with primes and I just simply generated all numbers out of primes that have no factors of n initially. I.e. built up sequence of combinations 3**k * 7**k ... until they've reached n.






            share|improve this answer




























              0














              Suggestions from @200_success will bring you speedup like from ~28.1s to ~11.8s (gcc 4.8.2 with -O3).
              Replacing all with gcd as suggested @EOF will give you ~11.4s and will save some memory.



              Overall idea is somewhat correct. You collect factors of n and check that there is no factors within other numbers (that are not already factors of n).



              But I guess you can improve solution by factoring with primes and avoid populating num with numbers like 4, 6, 8, 9 etc. That brings time to ~1.3s.



              for (int i = 2; i < n; i++)
              {
              if (n % i == 0)
              {
              bool foundFactor = false;
              for (int j = 0; j < num.size(); ++j)
              {
              if (i % num[j] == 0)
              {
              foundFactor = true;
              break;
              }
              }
              if (!foundFactor) num.push_back(i);
              continue;
              }
              bool foundFactor = false;
              for (int j = 0; j < num.size(); ++j)
              {
              if (i % num[j] == 0)
              {
              foundFactor = true;
              break;
              }
              }
              if (!foundFactor)
              cntr++;
              }


              For your n = 1000000000 I've got ~13.6s



              Note that there is a linear relation beetween numbers of co-primes in 1000000000 and 1000. That's because the only difference between them is (2*5)**k. That leads us to another optimization based on the wheel factorization:



              long long wheel = 1;

              // factorization of n
              for (long long i = 2, m = n; i <= m; i++)
              {
              if (m % i == 0)
              {
              num.push_back(i);
              wheel *= i; // re-size wheel
              // remove powers of i from m
              do { m /= i; } while (m % i == 0);
              }
              }

              for (int i = 2; i < wheel; i++)
              {
              if (n % i == 0)
              {
              continue;
              }
              bool foundFactor = false;
              for (int j = 0; j < num.size() && num[j] < i; ++j)
              {
              if (i % num[j] == 0)
              {
              foundFactor = true;
              break;
              }
              }
              if (!foundFactor)
              cntr++;
              }
              cout << cntr+1 << endl;
              cout << (cntr+1)*n/wheel << endl;


              That gives ~0s for almost any 10**k



              P.S. It sound pretty much as Project Euler problem I've met once. I used a bit different approach. I already had a pretty good framework for working with primes and I just simply generated all numbers out of primes that have no factors of n initially. I.e. built up sequence of combinations 3**k * 7**k ... until they've reached n.






              share|improve this answer


























                0












                0








                0






                Suggestions from @200_success will bring you speedup like from ~28.1s to ~11.8s (gcc 4.8.2 with -O3).
                Replacing all with gcd as suggested @EOF will give you ~11.4s and will save some memory.



                Overall idea is somewhat correct. You collect factors of n and check that there is no factors within other numbers (that are not already factors of n).



                But I guess you can improve solution by factoring with primes and avoid populating num with numbers like 4, 6, 8, 9 etc. That brings time to ~1.3s.



                for (int i = 2; i < n; i++)
                {
                if (n % i == 0)
                {
                bool foundFactor = false;
                for (int j = 0; j < num.size(); ++j)
                {
                if (i % num[j] == 0)
                {
                foundFactor = true;
                break;
                }
                }
                if (!foundFactor) num.push_back(i);
                continue;
                }
                bool foundFactor = false;
                for (int j = 0; j < num.size(); ++j)
                {
                if (i % num[j] == 0)
                {
                foundFactor = true;
                break;
                }
                }
                if (!foundFactor)
                cntr++;
                }


                For your n = 1000000000 I've got ~13.6s



                Note that there is a linear relation beetween numbers of co-primes in 1000000000 and 1000. That's because the only difference between them is (2*5)**k. That leads us to another optimization based on the wheel factorization:



                long long wheel = 1;

                // factorization of n
                for (long long i = 2, m = n; i <= m; i++)
                {
                if (m % i == 0)
                {
                num.push_back(i);
                wheel *= i; // re-size wheel
                // remove powers of i from m
                do { m /= i; } while (m % i == 0);
                }
                }

                for (int i = 2; i < wheel; i++)
                {
                if (n % i == 0)
                {
                continue;
                }
                bool foundFactor = false;
                for (int j = 0; j < num.size() && num[j] < i; ++j)
                {
                if (i % num[j] == 0)
                {
                foundFactor = true;
                break;
                }
                }
                if (!foundFactor)
                cntr++;
                }
                cout << cntr+1 << endl;
                cout << (cntr+1)*n/wheel << endl;


                That gives ~0s for almost any 10**k



                P.S. It sound pretty much as Project Euler problem I've met once. I used a bit different approach. I already had a pretty good framework for working with primes and I just simply generated all numbers out of primes that have no factors of n initially. I.e. built up sequence of combinations 3**k * 7**k ... until they've reached n.






                share|improve this answer














                Suggestions from @200_success will bring you speedup like from ~28.1s to ~11.8s (gcc 4.8.2 with -O3).
                Replacing all with gcd as suggested @EOF will give you ~11.4s and will save some memory.



                Overall idea is somewhat correct. You collect factors of n and check that there is no factors within other numbers (that are not already factors of n).



                But I guess you can improve solution by factoring with primes and avoid populating num with numbers like 4, 6, 8, 9 etc. That brings time to ~1.3s.



                for (int i = 2; i < n; i++)
                {
                if (n % i == 0)
                {
                bool foundFactor = false;
                for (int j = 0; j < num.size(); ++j)
                {
                if (i % num[j] == 0)
                {
                foundFactor = true;
                break;
                }
                }
                if (!foundFactor) num.push_back(i);
                continue;
                }
                bool foundFactor = false;
                for (int j = 0; j < num.size(); ++j)
                {
                if (i % num[j] == 0)
                {
                foundFactor = true;
                break;
                }
                }
                if (!foundFactor)
                cntr++;
                }


                For your n = 1000000000 I've got ~13.6s



                Note that there is a linear relation beetween numbers of co-primes in 1000000000 and 1000. That's because the only difference between them is (2*5)**k. That leads us to another optimization based on the wheel factorization:



                long long wheel = 1;

                // factorization of n
                for (long long i = 2, m = n; i <= m; i++)
                {
                if (m % i == 0)
                {
                num.push_back(i);
                wheel *= i; // re-size wheel
                // remove powers of i from m
                do { m /= i; } while (m % i == 0);
                }
                }

                for (int i = 2; i < wheel; i++)
                {
                if (n % i == 0)
                {
                continue;
                }
                bool foundFactor = false;
                for (int j = 0; j < num.size() && num[j] < i; ++j)
                {
                if (i % num[j] == 0)
                {
                foundFactor = true;
                break;
                }
                }
                if (!foundFactor)
                cntr++;
                }
                cout << cntr+1 << endl;
                cout << (cntr+1)*n/wheel << endl;


                That gives ~0s for almost any 10**k



                P.S. It sound pretty much as Project Euler problem I've met once. I used a bit different approach. I already had a pretty good framework for working with primes and I just simply generated all numbers out of primes that have no factors of n initially. I.e. built up sequence of combinations 3**k * 7**k ... until they've reached n.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jan 13 '14 at 9:31

























                answered Jan 13 '14 at 8:56









                ony

                61135




                61135























                    0














                    I don't know if you still need this, since it is a very old question. I wrote it for anybody else who might be looking for the answer.



                    This counts every N's "relatively prime number" (less then N). It is called Eulers' totient function.



                    #include <cstdio>
                    typedef long long lld;

                    lld f(lld num)
                    {
                    lld ans = num;
                    for (lld i = 2; i*i <= num; i++)
                    {
                    if (num%i==0)
                    {
                    while (num%i==0) num /= i;
                    ans -= ans / i;
                    }
                    }
                    if (num > 1)
                    ans -= ans / num;
                    return ans;
                    }

                    int main()
                    {
                    lld N;
                    scanf("%lld", &N);
                    printf("%lld", f(N));
                    }





                    share|improve this answer























                    • Euler's totient function
                      – Gs_
                      Jun 7 '17 at 13:16






                    • 2




                      This is basically a code dump answer (even after moving the explanatory text to the top). Every answer must make at least one insightful observation about the code in the question and not just offer an alternative implementation without at least explaining what it does better or how. See the help-center for more information.
                      – Graipher
                      Jun 7 '17 at 13:36


















                    0














                    I don't know if you still need this, since it is a very old question. I wrote it for anybody else who might be looking for the answer.



                    This counts every N's "relatively prime number" (less then N). It is called Eulers' totient function.



                    #include <cstdio>
                    typedef long long lld;

                    lld f(lld num)
                    {
                    lld ans = num;
                    for (lld i = 2; i*i <= num; i++)
                    {
                    if (num%i==0)
                    {
                    while (num%i==0) num /= i;
                    ans -= ans / i;
                    }
                    }
                    if (num > 1)
                    ans -= ans / num;
                    return ans;
                    }

                    int main()
                    {
                    lld N;
                    scanf("%lld", &N);
                    printf("%lld", f(N));
                    }





                    share|improve this answer























                    • Euler's totient function
                      – Gs_
                      Jun 7 '17 at 13:16






                    • 2




                      This is basically a code dump answer (even after moving the explanatory text to the top). Every answer must make at least one insightful observation about the code in the question and not just offer an alternative implementation without at least explaining what it does better or how. See the help-center for more information.
                      – Graipher
                      Jun 7 '17 at 13:36
















                    0












                    0








                    0






                    I don't know if you still need this, since it is a very old question. I wrote it for anybody else who might be looking for the answer.



                    This counts every N's "relatively prime number" (less then N). It is called Eulers' totient function.



                    #include <cstdio>
                    typedef long long lld;

                    lld f(lld num)
                    {
                    lld ans = num;
                    for (lld i = 2; i*i <= num; i++)
                    {
                    if (num%i==0)
                    {
                    while (num%i==0) num /= i;
                    ans -= ans / i;
                    }
                    }
                    if (num > 1)
                    ans -= ans / num;
                    return ans;
                    }

                    int main()
                    {
                    lld N;
                    scanf("%lld", &N);
                    printf("%lld", f(N));
                    }





                    share|improve this answer














                    I don't know if you still need this, since it is a very old question. I wrote it for anybody else who might be looking for the answer.



                    This counts every N's "relatively prime number" (less then N). It is called Eulers' totient function.



                    #include <cstdio>
                    typedef long long lld;

                    lld f(lld num)
                    {
                    lld ans = num;
                    for (lld i = 2; i*i <= num; i++)
                    {
                    if (num%i==0)
                    {
                    while (num%i==0) num /= i;
                    ans -= ans / i;
                    }
                    }
                    if (num > 1)
                    ans -= ans / num;
                    return ans;
                    }

                    int main()
                    {
                    lld N;
                    scanf("%lld", &N);
                    printf("%lld", f(N));
                    }






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jun 7 '17 at 13:33









                    Graipher

                    23.6k53585




                    23.6k53585










                    answered Jun 7 '17 at 13:11









                    Gs_

                    91




                    91












                    • Euler's totient function
                      – Gs_
                      Jun 7 '17 at 13:16






                    • 2




                      This is basically a code dump answer (even after moving the explanatory text to the top). Every answer must make at least one insightful observation about the code in the question and not just offer an alternative implementation without at least explaining what it does better or how. See the help-center for more information.
                      – Graipher
                      Jun 7 '17 at 13:36




















                    • Euler's totient function
                      – Gs_
                      Jun 7 '17 at 13:16






                    • 2




                      This is basically a code dump answer (even after moving the explanatory text to the top). Every answer must make at least one insightful observation about the code in the question and not just offer an alternative implementation without at least explaining what it does better or how. See the help-center for more information.
                      – Graipher
                      Jun 7 '17 at 13:36


















                    Euler's totient function
                    – Gs_
                    Jun 7 '17 at 13:16




                    Euler's totient function
                    – Gs_
                    Jun 7 '17 at 13:16




                    2




                    2




                    This is basically a code dump answer (even after moving the explanatory text to the top). Every answer must make at least one insightful observation about the code in the question and not just offer an alternative implementation without at least explaining what it does better or how. See the help-center for more information.
                    – Graipher
                    Jun 7 '17 at 13:36






                    This is basically a code dump answer (even after moving the explanatory text to the top). Every answer must make at least one insightful observation about the code in the question and not just offer an alternative implementation without at least explaining what it does better or how. See the help-center for more information.
                    – Graipher
                    Jun 7 '17 at 13:36













                    0














                    Gs_'s answer starts off by essentially finding all the prime factors of n. If you're going to do that, then you might as well use the following well-known formula that calculates the Euler function from the prime factorisation:



                    phi(p1 ^ a1 * ... * pk ^ ak) =
                    (p1 ^ a1 - p1 ^ (a1 - 1))
                    * ...
                    * (pk ^ ak - pk ^ (ak - 1))


                    The code would look something like this:



                    long long phi = 1;

                    // factorization of n
                    for (long long i = 2, m = n; m > 1; i++)
                    {
                    // Now phi(n/m) == phi
                    if (m % i == 0)
                    {
                    // i is the smallest prime factor of m, and is not a factor of n/m
                    m /= i;
                    phi *= (i - 1);
                    while (m % i == 0) {
                    m /= i;
                    phi *= i;
                    }
                    }
                    }

                    return phi;





                    share|improve this answer























                    • What's wheel?
                      – 200_success
                      Jan 13 '14 at 12:07










                    • @200_success That was in ony's code. I forgot to delete it. It's removed now. Thanks.
                      – David Knipe
                      Jan 13 '14 at 12:34
















                    0














                    Gs_'s answer starts off by essentially finding all the prime factors of n. If you're going to do that, then you might as well use the following well-known formula that calculates the Euler function from the prime factorisation:



                    phi(p1 ^ a1 * ... * pk ^ ak) =
                    (p1 ^ a1 - p1 ^ (a1 - 1))
                    * ...
                    * (pk ^ ak - pk ^ (ak - 1))


                    The code would look something like this:



                    long long phi = 1;

                    // factorization of n
                    for (long long i = 2, m = n; m > 1; i++)
                    {
                    // Now phi(n/m) == phi
                    if (m % i == 0)
                    {
                    // i is the smallest prime factor of m, and is not a factor of n/m
                    m /= i;
                    phi *= (i - 1);
                    while (m % i == 0) {
                    m /= i;
                    phi *= i;
                    }
                    }
                    }

                    return phi;





                    share|improve this answer























                    • What's wheel?
                      – 200_success
                      Jan 13 '14 at 12:07










                    • @200_success That was in ony's code. I forgot to delete it. It's removed now. Thanks.
                      – David Knipe
                      Jan 13 '14 at 12:34














                    0












                    0








                    0






                    Gs_'s answer starts off by essentially finding all the prime factors of n. If you're going to do that, then you might as well use the following well-known formula that calculates the Euler function from the prime factorisation:



                    phi(p1 ^ a1 * ... * pk ^ ak) =
                    (p1 ^ a1 - p1 ^ (a1 - 1))
                    * ...
                    * (pk ^ ak - pk ^ (ak - 1))


                    The code would look something like this:



                    long long phi = 1;

                    // factorization of n
                    for (long long i = 2, m = n; m > 1; i++)
                    {
                    // Now phi(n/m) == phi
                    if (m % i == 0)
                    {
                    // i is the smallest prime factor of m, and is not a factor of n/m
                    m /= i;
                    phi *= (i - 1);
                    while (m % i == 0) {
                    m /= i;
                    phi *= i;
                    }
                    }
                    }

                    return phi;





                    share|improve this answer














                    Gs_'s answer starts off by essentially finding all the prime factors of n. If you're going to do that, then you might as well use the following well-known formula that calculates the Euler function from the prime factorisation:



                    phi(p1 ^ a1 * ... * pk ^ ak) =
                    (p1 ^ a1 - p1 ^ (a1 - 1))
                    * ...
                    * (pk ^ ak - pk ^ (ak - 1))


                    The code would look something like this:



                    long long phi = 1;

                    // factorization of n
                    for (long long i = 2, m = n; m > 1; i++)
                    {
                    // Now phi(n/m) == phi
                    if (m % i == 0)
                    {
                    // i is the smallest prime factor of m, and is not a factor of n/m
                    m /= i;
                    phi *= (i - 1);
                    while (m % i == 0) {
                    m /= i;
                    phi *= i;
                    }
                    }
                    }

                    return phi;






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jan 1 at 20:08

























                    answered Jan 13 '14 at 11:22









                    David Knipe

                    1764




                    1764












                    • What's wheel?
                      – 200_success
                      Jan 13 '14 at 12:07










                    • @200_success That was in ony's code. I forgot to delete it. It's removed now. Thanks.
                      – David Knipe
                      Jan 13 '14 at 12:34


















                    • What's wheel?
                      – 200_success
                      Jan 13 '14 at 12:07










                    • @200_success That was in ony's code. I forgot to delete it. It's removed now. Thanks.
                      – David Knipe
                      Jan 13 '14 at 12:34
















                    What's wheel?
                    – 200_success
                    Jan 13 '14 at 12:07




                    What's wheel?
                    – 200_success
                    Jan 13 '14 at 12:07












                    @200_success That was in ony's code. I forgot to delete it. It's removed now. Thanks.
                    – David Knipe
                    Jan 13 '14 at 12:34




                    @200_success That was in ony's code. I forgot to delete it. It's removed now. Thanks.
                    – David Knipe
                    Jan 13 '14 at 12:34


















                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Code Review Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f39109%2frelative-prime-numbers%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Список кардиналов, возведённых папой римским Каликстом III

                    Deduzione

                    Mysql.sock missing - “Can't connect to local MySQL server through socket”