Search code examples
c++functioncomma-operator

Can't understand this code?


Can anyone help me in understanding the following code:-

int r, countIt(int n) {
    while (r += "            2  "[n % 10] & 3, n /= 10);
    return r;
}

I found this code in one of the challenges of codefights.com, https://codefights.com/challenge/v5Zg8trjoun3PTxrZ/solutions/Aj3ppbhSShixt4nBi

This is a solution for counting number of holes in a number.
e.g.

1111 = 0  
0000 = 4  
1234 = 0  
8888 = 8   

I am not able to understand the following things:
1. Logic of this code
2. comma (,) operator used in return data type of the function
3. Use of []operator after string.
4. And actually the whole code.


Solution

  • I looked up the link you provided. After carefully observing the code i came to following conclusion.

    int r, countIt(int n) {.....}
    

    is equivalent to writing as

    int r;
    int countIt(int n){.....}
    

    now for

    while (r += "            2  "[n % 10] & 3, n /= 10);
    

    is equivalent to:

    do{
        r += "           2  "[n % 10] & 3;
        n/=10;
    }while(n);
    

    Now comes the logical part of the code

    r += "           2  "[n % 10] & 3;
    

    let me give you some basics.

    1. In c++

    cout<<"abcde"[2];

    will give you output

    c
    

    now if you watch carefully the code in link which you provided its something like this:

    r += "           2  "[n % 10] & 3;
    

    is nothing but

    r += "TAB,SPACE,SPACE,SPACE,SPACE,SPACE,TAB,SPACE,2,TAB"[n % 10] & 3;
    

    Now its time to explain how this code is calculating number of holes. The ASCII value of TAB is 9 whose binary equivalent is 1001. The ASCII value of SPACE is 32 whose binary equivalent is 100000.

    so bit wise anding TAB with 3 will result

                1001 & 0011 = 0001    which is 1
    

    bit wise anding SPACE with 3 will result

                100000 & 000011 = 000000   which is 0
    

    replacing TABs with 1 and SPACEs with 0 hence this concludes as writing

    do{
        r += "1000001021"[n % 10] & 3;
        n/=10;
    }while(n);
    

    n % 10 is the low-order decimal digit of n. We use that as an index into a string literal, which contains information about how many holes is there in that low-order decimal digit then add it to result r.