Sanitator's blog

By Sanitator, history, 5 weeks ago, translation, In English,

Debugging the traditional way

Virtually every competitive programmer has at least once printed to console the values from some container, or array, or just a variable during debugging. This is where appear those ugly nested loops which take some time to write:

    vector<int> a[4][6] = {{{2,3}, {4}}, {{6,2}, {4,5}}};

    for(int i = 1; i < size(a); ++i, cout << endl){
        for(int j = 1; j < size(a[i]); ++j, cout << endl){
            for(int k : a[i][j]){
                cout << k << ' ';
            }
        }
    }

OMG, and bound checking for simple output of an array of vectors? 2D, 3D, it doesn't matter anymore if we can't write it concisely. And those stupid endls for empty cells...

Debugging with dbg()

I was fed up with traditional methods and wrote a simple several-liner for printing almost everything one might want. I like it, though it has some limitations. It's hugely inspired by this submission by tourist.

You can find my code here.

The compact version is created from the extended one by means of http://removelinebreaks.net/.

How to use dbg()

Suppose we have some nested containers(vector, string, bitset, set, map) or arrays, which for simplicity we may consider a multidimensional array with some specific dimensions. dbg() can neatly print the name, bounds and, at last, the values from this sub-array.

For example:

    string g[2][2] = {{"file", "input"}, {"file", "output"}};
    dbg(g,0,1,0,1,0,1);

// output:
[g,0,1,0,1,0,1]: 
[["fi", "in"], 
 ["fi", "ou"]]

To do so, you pass the name of array and [two closed bounds] for each dimension(btw, you can omit several last bounds). If they are too large, dbg() reduces them so that they are inside the arr. By default the bounds are set on the start and the end of each dimension.

ATTENTION!

++If you pass bounds [l;r] to the dimension that is map or set, the output goes from the lth largest key to the rth largest, or to the last element of dimension(if r is too big).

++dbg() works with c-arrays whose sizes of dimensions are constant and are known at compile time.

first example
second example

++If you set the incorrect bounds, the empty lines instead of values of container are printed.

/*-----------------------------------------------*/

Let's look at the container's elements from 1st to 2nd

    map<vector<int>, vector<string>> a = {{{3,4},{"sauron"}}, {{1,2},{"gandalf", "the", "gray"}}, {{5},{"frodo","bilbo"}}};
    
    // traditional version
    auto l = begin(a), r = begin(a);
    advance(l,1), advance(r, min(int(a.size()), 3));
    for(; l != r; ++l){
        cout << "{"; for(auto &ff : (*l).first) cout << ff << ","; cout << "}";
        cout << "{"; for(auto &ff : (*l).second) cout << ff << ","; cout << "}\n";
    } cout << "\n";
    
// output: 
{3,4,}{sauron,}
{5,}{frodo,bilbo,}

    // dbg():
    dbg(a,1,2);

// output:
[a,1,2]: 
[([3, 4], ["sauron"]), ([5], ["frodo", "bilbo"])]

/*-----------------------------------------------*/

Let's print some variables

    int t = 5; char u = 'R';
    pair<pair<double, unsigned int>, pair<int, string>> v = {{234.34534, 42}, {133, "IOI"}};
    
    // traditional version:
    #define fi first
    #define se second
    cout << t << " | " << u << " | " << "{ { " << v.fi.fi << "," << v.fi.se << " }{ " << v.se.fi << "," << v.se.se << " } }\n"; 
    
// output:
5 | R | { { 234.345,42 }{ 133,IOI } }


    // dbg
    dbg(t), dbg(u), dbg(v);
   
// output
[t]: 5

[u]: R

[v]: ((234.345340,42),(133,"IOI"))
    

/*-----------------------------------------------*/

Hope this function saves your precious minutes during contests. Enjoy!

UPD: egregious bug with bitsets fixed

 
 
 
 
  • Vote: I like it  
  • +59
  • Vote: I do not like it  

»
5 weeks ago, # |
  Vote: I like it +66 Vote: I do not like it

I'd rather use my shitty debugging skills which I understand than using something cryptic like this.

  • »
    »
    5 weeks ago, # ^ |
    Rev. 3   Vote: I like it +20 Vote: I do not like it

    true , lol but still we should appreciate the poster for trying to help community.

  • »
    »
    5 weeks ago, # ^ |
    Rev. 2   Vote: I like it +40 Vote: I do not like it

    Well, I just wanted to share my shitty debugging skills

»
5 weeks ago, # |
  Vote: I like it +157 Vote: I do not like it

One of your "four lines" has more than 2000 characters...

  • »
    »
    5 weeks ago, # ^ |
      Vote: I like it +16 Vote: I do not like it

    I would also like to thank MikeMirzayanov for the great Codeforces Custom invocation which doesn't have automatic line breaking

  • »
    »
    5 weeks ago, # ^ |
    Rev. 4   Vote: I like it -29 Vote: I do not like it

    Look at my beautiful debugger! It's less than 1600 now!

»
5 weeks ago, # |
  Vote: I like it +8 Vote: I do not like it

While your function seems to work, why did you obfuscate everything in a single line? Good luck changing the function in case you have a bug or want to add something new to it...

  • »
    »
    5 weeks ago, # ^ |
    Rev. 6   Vote: I like it +3 Vote: I do not like it

    Because I provided extended code in the post. And it's easier to copy-paste 4 lines of code, than 42

»
5 weeks ago, # |
  Vote: I like it +33 Vote: I do not like it

Every time I see the things people use to debug in C++ (how did this ever pass review I wonder?), I'm glad I switched to D quite a while ago.

example

Perhaps in 20 years, the C++ committee will agree on a feasible means of debug output to have in the standard library. But life, or ICPC eligibility, or whatever other contests, they are here and now.

»
5 weeks ago, # |
Rev. 2   Vote: I like it +9 Vote: I do not like it

You are gonna save a lot of time of guys like us, in the upcoming journey of CP.

Thanks a lot.

»
5 weeks ago, # |
  Vote: I like it +25 Vote: I do not like it
let x = vec![vec![1, 2, 3], vec![4, 5]];
println!("{:?}", x);

laughs in rust

»
4 weeks ago, # |
Rev. 6   Vote: I like it -34 Vote: I do not like it

I left my team

»
4 weeks ago, # |
  Vote: I like it +14 Vote: I do not like it

Anyway, you will never have this in a formal competition.

»
4 weeks ago, # |
  Vote: I like it 0 Vote: I do not like it

this is clearly a work of a retard.

»
4 weeks ago, # |
  Vote: I like it +5 Vote: I do not like it

Sanitator, Its very helpful. I came across a bug, hope you fix it soon.

code
output
  • »
    »
    4 weeks ago, # ^ |
    Rev. 3   Vote: I like it +5 Vote: I do not like it

    though it has some limitations

    Frankly speaking, currently I can't come up with idea how to not manually pass the sizes of dimensions of a variable sized array to dbg(), so the only thing I could suggest is to set constant sizes of dimensions of arrays at compile time. Any ideas without specific functions for 2D, 3D... arrays?

    first option
    first option
»
4 weeks ago, # |
  Vote: I like it +8 Vote: I do not like it

I wonder where were LanceTheDragonTrainer