#include <initializer_list>
#include <iostream>
#include <unordered_map>
#include <vector>
struct Node {
int x, y;
std::vector<Node *> children;
Node() : x(0), y(0), children()
{
}
Node(const std::initializer_list<Node *> &nodes)
: x(0), y(0), children(nodes)
{
}
};
void
place(Node *n, int y, int x, std::unordered_map<int, int> &leftFront)
{
if (x < 0) {
x = 0;
}
if (leftFront.find(y) != leftFront.cend() && x <= leftFront[y]) {
x = leftFront[y] + 1;
}
n->y = y;
const int nchildren = n->children.size();
const int width = nchildren + (1 - nchildren%2);
int childX = x - width/2;
int i = 0;
Node *p; // previous child
for (Node *c : n->children) {
place(c, y + 1, childX, leftFront);
childX = c->x;
if (nchildren%2 == 0) {
if (i == nchildren/2) {
x = (c->x + p->x + 1)/2; // or (c->x + p->x)/2 to place root
// closer to previous child
}
if (i == nchildren/2 - 1) {
++childX;
}
} else {
if (i == nchildren/2) {
x = childX;
}
}
++childX;
++i;
p = c;
}
n->x = x;
leftFront[y] = x;
}
void draw(Node *n, std::vector<std::string> &screen)
{
screen[n->y].resize(n->x + 1, ' ');
screen[n->y][n->x] = '*';
for (Node *c : n->children) {
draw(c, screen);
}
}
void
doIt(const std::string &title, Node *root)
{
std::cout << title << ':' << std::endl;
std::unordered_map<int, int> leftFront;
place(root, 0, 0, leftFront);
std::vector<std::string> screen(5); // XXX: hardcoded
draw(root, screen);
for (const std::string &l : screen) {
std::cout << l << std::endl;
}
}
int
main(void)
{
{
Node n40;
Node n30;
Node n31 = { &n40 };
Node n21 = { &n30, &n31 };
Node n20;
Node n12 = { &n21 };
Node n11 = { &n20 };
Node n10;
Node n00 = { &n10, &n11, &n12 };
doIt("original tree", &n00);
}
{
Node n40;
Node n30;
Node n31 = { &n40 };
Node n24 = { &n30, &n31 };
Node n23;
Node n22;
Node n21;
Node n20;
Node n12 = { &n24 };
Node n11 = { &n22, &n23 };
Node n10 = { &n20, &n21 };
Node n00 = { &n10, &n11, &n12 };
doIt("more complicated tree", &n00);
}
{
Node n40;
Node n30;
Node n31 = { &n40 };
Node n24 = { &n30, &n31 };
Node n23;
Node n22;
Node n21;
Node n20;
Node n12 = { &n24 };
Node n11 = { &n22, &n23 };
Node n10 = { &n20, &n21 };
Node n00 = { &n10, &n11 };
doIt("perfect binary tree", &n00);
}
return 0;
}
I2luY2x1ZGUgPGluaXRpYWxpemVyX2xpc3Q+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHVub3JkZXJlZF9tYXA+CiNpbmNsdWRlIDx2ZWN0b3I+CgpzdHJ1Y3QgTm9kZSB7CiAgICBpbnQgeCwgeTsKICAgIHN0ZDo6dmVjdG9yPE5vZGUgKj4gY2hpbGRyZW47CgogICAgTm9kZSgpIDogeCgwKSwgeSgwKSwgY2hpbGRyZW4oKQogICAgewogICAgfQogICAgTm9kZShjb25zdCBzdGQ6OmluaXRpYWxpemVyX2xpc3Q8Tm9kZSAqPiAmbm9kZXMpCiAgICAgICAgOiB4KDApLCB5KDApLCBjaGlsZHJlbihub2RlcykKICAgIHsKICAgIH0KfTsKCnZvaWQKcGxhY2UoTm9kZSAqbiwgaW50IHksIGludCB4LCBzdGQ6OnVub3JkZXJlZF9tYXA8aW50LCBpbnQ+ICZsZWZ0RnJvbnQpCnsKICAgIGlmICh4IDwgMCkgewogICAgICAgIHggPSAwOwogICAgfQogICAgaWYgKGxlZnRGcm9udC5maW5kKHkpICE9IGxlZnRGcm9udC5jZW5kKCkgJiYgeCA8PSBsZWZ0RnJvbnRbeV0pIHsKICAgICAgICB4ID0gbGVmdEZyb250W3ldICsgMTsKICAgIH0KCiAgICBuLT55ID0geTsKCiAgICBjb25zdCBpbnQgbmNoaWxkcmVuID0gbi0+Y2hpbGRyZW4uc2l6ZSgpOwogICAgY29uc3QgaW50IHdpZHRoID0gbmNoaWxkcmVuICsgKDEgLSBuY2hpbGRyZW4lMik7CiAgICBpbnQgY2hpbGRYID0geCAtIHdpZHRoLzI7CiAgICBpbnQgaSA9IDA7CiAgICBOb2RlICpwOyAvLyBwcmV2aW91cyBjaGlsZAogICAgZm9yIChOb2RlICpjIDogbi0+Y2hpbGRyZW4pIHsKICAgICAgICBwbGFjZShjLCB5ICsgMSwgY2hpbGRYLCBsZWZ0RnJvbnQpOwoKICAgICAgICBjaGlsZFggPSBjLT54OwogICAgICAgIGlmIChuY2hpbGRyZW4lMiA9PSAwKSB7CiAgICAgICAgICAgIGlmIChpID09IG5jaGlsZHJlbi8yKSB7CiAgICAgICAgICAgICAgICB4ID0gKGMtPnggKyBwLT54ICsgMSkvMjsgLy8gb3IgKGMtPnggKyBwLT54KS8yIHRvIHBsYWNlIHJvb3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjbG9zZXIgdG8gcHJldmlvdXMgY2hpbGQKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaSA9PSBuY2hpbGRyZW4vMiAtIDEpIHsKICAgICAgICAgICAgICAgICsrY2hpbGRYOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKGkgPT0gbmNoaWxkcmVuLzIpIHsKICAgICAgICAgICAgICAgIHggPSBjaGlsZFg7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgKytjaGlsZFg7CiAgICAgICAgKytpOwoKICAgICAgICBwID0gYzsKICAgIH0KCiAgICBuLT54ID0geDsKICAgIGxlZnRGcm9udFt5XSA9IHg7Cn0KCnZvaWQgZHJhdyhOb2RlICpuLCBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4gJnNjcmVlbikKewogICAgc2NyZWVuW24tPnldLnJlc2l6ZShuLT54ICsgMSwgJyAnKTsKICAgIHNjcmVlbltuLT55XVtuLT54XSA9ICcqJzsKICAgIGZvciAoTm9kZSAqYyA6IG4tPmNoaWxkcmVuKSB7CiAgICAgICAgZHJhdyhjLCBzY3JlZW4pOwogICAgfQp9Cgp2b2lkCmRvSXQoY29uc3Qgc3RkOjpzdHJpbmcgJnRpdGxlLCBOb2RlICpyb290KQp7CiAgICBzdGQ6OmNvdXQgPDwgdGl0bGUgPDwgJzonIDw8IHN0ZDo6ZW5kbDsKCiAgICBzdGQ6OnVub3JkZXJlZF9tYXA8aW50LCBpbnQ+IGxlZnRGcm9udDsKICAgIHBsYWNlKHJvb3QsIDAsIDAsIGxlZnRGcm9udCk7CgogICAgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IHNjcmVlbig1KTsgLy8gWFhYOiBoYXJkY29kZWQKICAgIGRyYXcocm9vdCwgc2NyZWVuKTsKCiAgICBmb3IgKGNvbnN0IHN0ZDo6c3RyaW5nICZsIDogc2NyZWVuKSB7CiAgICAgICAgc3RkOjpjb3V0IDw8IGwgPDwgc3RkOjplbmRsOwogICAgfQp9CgppbnQKbWFpbih2b2lkKQp7CiAgICB7CiAgICAgICAgTm9kZSBuNDA7CiAgICAgICAgTm9kZSBuMzA7CiAgICAgICAgTm9kZSBuMzEgPSB7ICZuNDAgfTsKICAgICAgICBOb2RlIG4yMSA9IHsgJm4zMCwgJm4zMSB9OwogICAgICAgIE5vZGUgbjIwOwogICAgICAgIE5vZGUgbjEyID0geyAmbjIxIH07CiAgICAgICAgTm9kZSBuMTEgPSB7ICZuMjAgfTsKICAgICAgICBOb2RlIG4xMDsKICAgICAgICBOb2RlIG4wMCA9IHsgJm4xMCwgJm4xMSwgJm4xMiB9OwogICAgICAgIGRvSXQoIm9yaWdpbmFsIHRyZWUiLCAmbjAwKTsKICAgIH0KCiAgICB7CiAgICAgICAgTm9kZSBuNDA7CiAgICAgICAgTm9kZSBuMzA7CiAgICAgICAgTm9kZSBuMzEgPSB7ICZuNDAgfTsKICAgICAgICBOb2RlIG4yNCA9IHsgJm4zMCwgJm4zMSB9OwogICAgICAgIE5vZGUgbjIzOwogICAgICAgIE5vZGUgbjIyOwogICAgICAgIE5vZGUgbjIxOwogICAgICAgIE5vZGUgbjIwOwogICAgICAgIE5vZGUgbjEyID0geyAmbjI0IH07CiAgICAgICAgTm9kZSBuMTEgPSB7ICZuMjIsICZuMjMgfTsKICAgICAgICBOb2RlIG4xMCA9IHsgJm4yMCwgJm4yMSB9OwogICAgICAgIE5vZGUgbjAwID0geyAmbjEwLCAmbjExLCAmbjEyIH07CiAgICAgICAgZG9JdCgibW9yZSBjb21wbGljYXRlZCB0cmVlIiwgJm4wMCk7CiAgICB9CgogICAgewogICAgICAgIE5vZGUgbjQwOwogICAgICAgIE5vZGUgbjMwOwogICAgICAgIE5vZGUgbjMxID0geyAmbjQwIH07CiAgICAgICAgTm9kZSBuMjQgPSB7ICZuMzAsICZuMzEgfTsKICAgICAgICBOb2RlIG4yMzsKICAgICAgICBOb2RlIG4yMjsKICAgICAgICBOb2RlIG4yMTsKICAgICAgICBOb2RlIG4yMDsKICAgICAgICBOb2RlIG4xMiA9IHsgJm4yNCB9OwogICAgICAgIE5vZGUgbjExID0geyAmbjIyLCAmbjIzIH07CiAgICAgICAgTm9kZSBuMTAgPSB7ICZuMjAsICZuMjEgfTsKICAgICAgICBOb2RlIG4wMCA9IHsgJm4xMCwgJm4xMSB9OwogICAgICAgIGRvSXQoInBlcmZlY3QgYmluYXJ5IHRyZWUiLCAmbjAwKTsKICAgIH0KCiAgICByZXR1cm4gMDsKfQ==