0

I've got unexpected \u0000 at leetcode:

enter image description here

Same code works fine locally in linqpad:

public string AddBinary(string a, string b)
{
    var result = a.Length > b.Length
        ? new char[a.Length]
        : new char[b.Length];

    result.Dump();

    bool carry = false;
    
    var iA = a.Length - 1;
    var iB = b.Length - 1;

    while (!(iA < 0 && iB < 0))
    {
        var bA = iA < 0 ? false : a[iA] == '1';
        var bB = iB < 0 ? false : b[iB] == '1';

        //char cA = iA < 0 ? '-' : a[iA];
        //char cB = iB < 0 ? '-' : b[iB];
        //$"string a. i = {iA} cA = '{cA}' {bA}".Dump();
        //$"string b. i = {iB} cB = '{cB}' {bB}".Dump();
        
        bool bCurrent = bA ^ bB ^ carry;

        int position = iA < 0 ? iB : iA;
        
        result[position] = bCurrent ? '1' : '0';
        
        carry = carry 
                ? !(!bA && !bB)
                : bA && bB;
        
        iA--;
        iB--;
    }
    
    result.Dump();

    if(!carry)
        return new string(result);
        
    var newResult = new char[result.Length + 1];
    newResult[0] = '1';
    for (int i = 0; i < result.Length; i++)
    {
        newResult[i+1] = result[i];
        result[i].Dump();
    }
    result.Dump();
    var ab = new string(newResult);
    DisplayString(ab);
    ab.Dump();
    return ab;

    //var one = new char[] { '1' };
    //result.Dump();
    //var newResult = one.Concat(result);
    //newResult.Dump();
    //var r = new string(newResult.ToArray());
    //r.Dump();
    //return r;
}

(see DisplayString definition at John's Skeet page)

Here is some debug info during this test case:

enter image description here

Second version has same error:

enter image description here

So, there's no place where \u0000 came from. Is it an bug? Or maybe i miss something?

A K
  • 714
  • 17
  • 39
  • 1
    The problem is that `result[2] == '\0'` before copying – xanatos Dec 31 '20 at 12:47
  • When you say it looks ok in linqpad, check that linqpad isn't treating the first occurrence of \0 in a string as the terminator; e.g. if you put "Hello\0World" into a windows app label, it'll just say "Hello" – Caius Jard Dec 31 '20 at 12:48
  • 2
    Test with "1" and "111" (i.e. reverse the parameter order). Since you will see the bug clearly if you do that. https://dotnetfiddle.net/5BuZ4n _Note I am surprised you didn't test that scenario, since the screenshot shows it clearly as the failing scenario._ – mjwills Dec 31 '20 at 12:52
  • @mjwills Yes, you're right: i tested not 1 + 111, but 111 + 1 - thatswhy i can't reproduce bug. One hour of debugging facepalm.jpg :( – A K Dec 31 '20 at 13:35

1 Answers1

2

The error is in the calculation of the position:

int position = iA >= iB ? iA : iB;

You need to use the maximum position.

As you wrote, with 1 and 111, in the first loop you have: iA == 0, iB == 2, position == 0 instead of position == 2 (so you are writing the first element instead of the last)

xanatos
  • 109,618
  • 12
  • 197
  • 280
  • Hm, with this fix realy passes all of tests, although i don't understand why. So, thank you for helping, i'll think more about your explanation later. – A K Dec 31 '20 at 13:07
  • @AK Print the `position` value in the cycle and you'll see – xanatos Dec 31 '20 at 13:08
  • 1
    @ak your original code, with more debugging: https://ideone.com/0K2z95 – xanatos Dec 31 '20 at 13:14
  • wow, now i've got bug reproduced. Really my code shows 0 1 1, and your's show 2 1 0. https://i.stack.imgur.com/HV8kX.png – A K Dec 31 '20 at 13:31