1

My problem is the following:

I want to find a prime number less than N, which corresponding number in 2 base system contains the maximum amount of ones.

For example for N = 87 my program returned 31 (11111 in 2 base system).

I am looking for the better solution to solve this problem.

My algorithm looks like this:

static int Slow(int N)
{
    int maxCount = 0;
    int maxi = 5;

    for (int i = 5; i <= N; i+=2)
    {
        if (Isprime(i))
        {
           string x = ConvertToPBase(i, 2);
           int count = Count1In(x);
           if (count > maxCount)
           {
              maxCount = count;
              maxi = i;
           }
       }
    }

    return maxi;
}

my IsPrime method is the following:

static bool Isprime(int n)
{
    if (n == 2)
       return true;
    if (n == 3)
       return true;
    if (n % 2 == 0)
       return false;
    if (n % 3 == 0)
       return false;

    int i = 5;
    int w = 2;

    while (i * i <= n)
    {
        if (n % i == 0)
            return false;

        i += w;
        w = 6 - w;
    }

    return true;
}    

My ConvertToPBase method is the following:

static string ConvertToPBase(int numberInTenBase, int P)
{
    List<int> list = new List<int>();
    while (numberInTenBase > 0)
    {
        list.Add((numberInTenBase % P));
        numberInTenBase /= P;
    }

    list.Reverse();
    string x = "";
    foreach (var item in list)
    {
        x += item;
    }
    return x;
}

My Count1In method looks like this:

static int Count1In(string x)
{
    int count = 0;

    for (int i = 0; i < x.Length; i++)
    {
        if (Convert.ToInt32(x[i].ToString()) == 1)
            count++;
    }

    return count;
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • What is not good about your solution? Or are you asking for a code review? – Silvermind Jun 04 '18 at 09:21
  • If this code is already working, then Stack Overflow isn't the place to as this I'm afraid. We only deal in specific programming issues, not broad statements like this. – DavidG Jun 04 '18 at 09:21
  • maybe I am making some extra steps in the first part of the code.. –  Jun 04 '18 at 09:22
  • @A.M If your code is _working_ completely, but you are trying to make it more efficient, you should post to [Code Review](https://codereview.stackexchange.com/) – ProgrammingLlama Jun 04 '18 at 09:25
  • I will post there, but community is small there... –  Jun 04 '18 at 09:26
  • What is the constraint for N? There is a function `Integer.bitCount(int)` which works in O(1) which should help fasten the process. – Pham Trung Jun 04 '18 at 09:26
  • @Pham Trung nothing... –  Jun 04 '18 at 09:27
  • So how fast your program is expected to be? with N is extremely large > 10^9, the only acceptable solution is O(1), which we may need to wait for quantum computer – Pham Trung Jun 04 '18 at 09:28
  • faster than this... Is Integer.Bitcount(int) avalaible in .NET? –  Jun 04 '18 at 09:30
  • 3
    The number of set bits in a binary number is known as its ["Hamming Weight"](https://en.wikipedia.org/wiki/Hamming_weight). That link has some efficient ways to calculate it. Having said that, the vast bulk of the time will be spent finding primes. Also see [this answer](https://stackoverflow.com/a/2709523/106159). – Matthew Watson Jun 04 '18 at 09:31
  • @MatthewWatson I will read it now.. –  Jun 04 '18 at 09:32
  • Oh, sorry, thought that this is Java, yes, as @MatthewWatson, you can implement Hamming Weight to improve your solution. If N is small, we can use faster algo to find prime also. But for unconstraint N, ... – Pham Trung Jun 04 '18 at 09:33
  • As for the "find primes" part, can you use the [Sieve](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes) (how big is `N`)? – Hans Kesting Jun 04 '18 at 09:46

1 Answers1

3

If you have a restriction over input value (value is int and thus value <= int.MaxValue) I suggest solving the problem for all possible bits set (1..30) and put the solutions into a collection, i.e.

            | min prime composed
   bits set |   binary | decimal
  -------------------------------
         1  |       10 |       2
         2  |       11 |       3
         3  |      111 |       7
         4  |    10111 |      23 
         5  |    11111 |      31
       ... 

Having this done, you can easily implement the solution as

   private static Dictionary<int, int> s_Solutions = new Dictionary<int, int>() {
     {0, int.MinValue},
     {1, 2},
     {2, 3},
     {3, 7},
     {4, 23},
     {5, 31},
     ... 
   };

   // O(1) solution - 31 items to scan only for the arbitrary N
   static int NotThatSlow(int N) {
     return s_Solutions
       .Where(pair => pair.Value < N)
       .OrderByDescending(pair => pair.Key)
       .Select(pair => pair.Value)
       .First(); 
   }
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215