HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Codility binary gap solution using regex

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
gapcodilitybinaryusingregexsolution

Problem

Below is the code I implemented to solve the binary gap problem:


Find longest sequence of zeros, bounded by ones, in binary representation of an integer.

However, it seems to be different from the answers out there. Is it because this is a bad approach in terms of performance? I wanted to get some ideas.

function binaryGap(number) {
    let binary = (number >>> 0).toString(2), // convert to binary
        regex = /(?!1)(0+)(?=1)/g; // regex to match zeros between 1s

    let matches = binary.match(regex);

    return matches ? matches.reduce(function(carry, current){
        return carry.length > current.length ? carry : current;
    }).length : 0;
}

Solution

The Regex is computationally heavy. I would consider simply iterating through the bits, keeping track of both the highest binary gap and the current binary gap. You could add optimizations such as that proposed by @konijn to bail out of iteration when you reach a point that you can no longer logically find a larger binary gap than your current max value.

That could be as simple as:

The following is updated per comments:

function binaryGap(number) {
    var binary = (number >>> 0).toString(2);
    var maxGap = 0;
    var currentGap = 0;
    var inGap = false;
    var length = binary.length;
    /*
    Fast return if binary string length is less than 3
    and no gap is possible
    */
    if(length = currentGap + length - i) {
            break;
        }
        if (inGap === false) {
           // we need to check to see if a new gap is started
           if (binary[i-1] === '1' && binary[i] === '0') {
               // we are in a new gap
               currentGap = 1;
               inGap = true;
           }
        } else {
           // we need to see if gap has ended
           if (binary[i] === '1') {
               // gap has ended
               if (currentGap > maxGap) {
                   maxGap = currentGap;
               }
               inGap = false;
           } else {
               // gap has continued
               currentGap++;
           }
        }
    }
    return maxGap;
}


Here is a simple performance test I set up comparing the approaches. Typically, I am seeing the bit iteration method working in about 20-25% of the time that the regex works.

Code Snippets

function binaryGap(number) {
    var binary = (number >>> 0).toString(2);
    var maxGap = 0;
    var currentGap = 0;
    var inGap = false;
    var length = binary.length;
    /*
    Fast return if binary string length is less than 3
    and no gap is possible
    */
    if(length < 3) {
        return 0;
    }
    /*
    Start iterating bits.  We start with second character.
    */
    for(var i = 1; i < length; i++) {
        /*
        See if we should continue evaluation based on whether
        we can actually exceed current maxGap number
        */
        if (maxGap >= currentGap + length - i) {
            break;
        }
        if (inGap === false) {
           // we need to check to see if a new gap is started
           if (binary[i-1] === '1' && binary[i] === '0') {
               // we are in a new gap
               currentGap = 1;
               inGap = true;
           }
        } else {
           // we need to see if gap has ended
           if (binary[i] === '1') {
               // gap has ended
               if (currentGap > maxGap) {
                   maxGap = currentGap;
               }
               inGap = false;
           } else {
               // gap has continued
               currentGap++;
           }
        }
    }
    return maxGap;
}

Context

StackExchange Code Review Q#136739, answer score: 6

Revisions (0)

No revisions yet.