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.
++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: dbgs() added — output without name