Using Bing and Hackerrank to solve Leetcode

This problem from Leetcode was a fun one 'cause I got to use the Bing + Hackerrank Partnership to solve it. Here is the problem https://leetcode.com/problems/prime-number-of-set-bits-in-binary-representation/description/:

Given two integers L and R, find the count of numbers in the range [L, R] (inclusive) having a prime number of set bits in their binary representation.
(Recall that the number of set bits an integer has is the number of 1s present when written in binary. For example, 21 written in binary is 10101 which has 3 set bits. Also, 1 is not a prime.)
Example 1:
Input: L = 6, R = 10
Output: 4
Explanation:
6 -> 110 (2 set bits, 2 is prime)
7 -> 111 (3 set bits, 3 is prime)
9 -> 1001 (2 set bits , 2 is prime)
10->1010 (2 set bits , 2 is prime)
Example 2:
Input: L = 10, R = 15
Output: 5
Explanation:
10 -> 1010 (2 set bits, 2 is prime)
11 -> 1011 (3 set bits, 3 is prime)
12 -> 1100 (2 set bits, 2 is prime)
13 -> 1101 (3 set bits, 3 is prime)
14 -> 1110 (3 set bits, 3 is prime)
15 -> 1111 (4 set bits, 4 is not prime)

Since we're going to use the primality test here, all you have to do is Bing Prime in C# and you will get the code right there for you!!!


If you try the same query on Google, well judge it by yourself


So with Bing you just search for the algorithm that you want, in the programming language that you wish for, and voila, you have the code that can be copied/pasted onto your project!
Rest of the logic is pretty straightforward:

  • Go to each number from L to R
  • Count the number of 1s by doing the module and division by two (or bit shifting)
  • Then call the IsPrime method and increment the count accordingly
Code is down below, cheers, Marcelo


public class Solution
{
public int CountPrimeSetBits(int L, int R)
{
int count = 0;

for (int i = L; i <= R; i++)
{
int temp = i;
int countOnes = 0;
while (temp > 0)
{
if (temp % 2 == 1) countOnes++;
temp /= 2;
}

count = IsPrime(countOnes) ? count + 1 : count;
}

return count;
}

static bool IsPrime(int n)
{
if (n < 2) return false;
if (n < 4) return true;
if (n % 2 == 0) return false;

double sqrt = System.Math.Sqrt(n);
int sqrtCeiling = (int)System.Math.Ceiling(sqrt);

for (int i = 3; i <= sqrtCeiling; i += 2)
if (n % i == 0) return false;
return true;
}
}

Comments

  1. Very nice, Marcelo! Your solution is nice and generic, but since this problem is marked as "easy" I decided to have a little fun with it and see how it can be solved using as few instructions and branches as possible. The first observation is that the range of numbers is limited to [1, 10^6], so 20 bits is sufficient to represent all of them. We can us this information to precompute all prime numbers in that range and replace isPrime function with a single lookup into a boolean array. The last observation is that there are super efficient algorithms for computing the number of set bits in a number and even though I can never remember that magic it's possible to steal it from https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel :)

    Using all observations above the code can look something like:

    class Solution {
    private:
    inline int numberOfSetBits(int v) {
    v = v - ((v >> 1) & 0x55555555);
    v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
    return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
    }
    public:
    int countPrimeSetBits(int L, int R) {
    // maximum number of bits in the range [1, 10^6] is 20, so
    // the only prime numbers we can encounter are: 2, 3, 5, 7, 11, 13, 17, 19
    bool is_prime[20] {false};
    is_prime[2] = is_prime[3] = is_prime[5] = is_prime[7] = is_prime[11] = is_prime[13] = is_prime[17] = is_prime[19] = true;
    int total = 0;
    for (int i = L; i <= R; ++i) total += is_prime[numberOfSetBits(i)];
    return total;
    }
    };

    The interesting thing about it is that it has an extremely low number of branches which is especially noticeable with the latest version of GCC compiler:

    countPrimeSetBits(int, int):
    pxor xmm0, xmm0
    cmp edi, esi
    mov DWORD PTR [rsp-24], 0
    mov BYTE PTR [rsp-21], 1
    mov BYTE PTR [rsp-23], 1
    movaps XMMWORD PTR [rsp-40], xmm0
    mov BYTE PTR [rsp-27], 1
    mov BYTE PTR [rsp-29], 1
    mov BYTE PTR [rsp-33], 1
    mov BYTE PTR [rsp-35], 1
    mov BYTE PTR [rsp-37], 1
    mov BYTE PTR [rsp-38], 1
    jg .L4
    add esi, 1
    xor eax, eax
    .L3:
    mov edx, edi
    mov ecx, edi
    add edi, 1
    sar edx
    and edx, 1431655765
    sub ecx, edx
    mov edx, ecx
    sar ecx, 2
    and edx, 858993459
    and ecx, 858993459
    add ecx, edx
    mov edx, ecx
    sar edx, 4
    add edx, ecx
    and edx, 252645135
    imul edx, edx, 16843009
    sar edx, 24
    movsx rdx, edx
    movzx edx, BYTE PTR [rsp-40+rdx]
    add eax, edx
    cmp edi, esi
    jne .L3
    rep ret
    .L4:
    xor eax, eax
    ret

    As you can see from the assembly code above, the entire code is fairly short, has very few branches and vectorized.

    Thanks for the sharing and have a splendid rest of the weekend!

    Reply Delete
  2. Wonderful observations!! Yeah I am with you, can’t never remember the fancy techniques to fetch the number of 1 bits in a number. Sadly this is still a common interview question in some companies (not Microsoft!). Cheers my friend!!!

    Reply Delete

Post a Comment

[フレーム]

Popular posts from this blog

Quasi FSM (Finite State Machine) problem + Vibe

Not really an FSM problem since the state isn't changing, it is just defined by the current input. Simply following the instructions should do it. Using VSCode IDE you can also engage the help of Cline or Copilot for a combo of coding and vibe coding, see below screenshot. Cheers, ACC. Process String with Special Operations I - LeetCode You are given a string  s  consisting of lowercase English letters and the special characters:  * ,  # , and  % . Build a new string  result  by processing  s  according to the following rules from left to right: If the letter is a  lowercase  English letter append it to  result . A  '*'   removes  the last character from  result , if it exists. A  '#'   duplicates  the current  result  and  appends  it to itself. A  '%'   reverses  the current  result . Return the final string  result  after processing all char...

Shortest Bridge – A BFS Story (with a Twist)

Here's another one from the Google 30 Days challenge on LeetCode — 934. Shortest Bridge . The goal? Given a 2D binary grid where two islands (groups of 1s) are separated by water (0s), flip the fewest number of 0s to 1s to connect them. Easy to describe. Sneaky to implement well. 🧭 My Approach My solution follows a two-phase Breadth-First Search (BFS) strategy: Find and mark one island : I start by scanning the grid until I find the first 1 , then use BFS to mark all connected land cells as 2 . I store their positions for later use. Bridge-building BFS : For each cell in the marked island, I run a BFS looking for the second island. Each BFS stops as soon as it hits a cell with value 1 . The minimum distance across all these searches gives the shortest bridge. πŸ” Code Snippet Here's the core logic simplified: public int ShortestBridge(int[][] grid) { // 1. Mark one island as '2' and gather its coordinates List<int> island = FindAndMark...

Classic Dynamic Programming IX

A bit of vibe code together with OpenAI O3. I asked O3 to just generate the sieve due to laziness. Sieve is used to calculate the first M primes (when I was using Miller-Rabin, was giving me TLE). The DP follows from that in a straightforward way: calculate the numbers from i..n-1, then n follows by calculating the min over all M primes. Notice that I made use of Goldbach's Conjecture as a way to optimize the code too. Goldbach's Conjecture estates that any even number greater than 2 is the sum of 2 primes. The conjecture is applied in the highlighted line. Cheers, ACC. PS: the prompt for the sieve was the following, again using Open AI O3 Advanced Reasoning: " give me a sieve to find the first M prime numbers in C#. The code should produce a List<int> with the first M primes " Minimum Number of Primes to Sum to Target - LeetCode You are given two integers  n  and  m . You have to select a multiset of  prime numbers  from the  first   m  pri...