"""
プログラミングのお題スレ Part17
https://m...content-available-to-author-only...h.net/test/read.cgi/tech/1584031367/
586:
お題: テキトーに木構造を描画せよ。
入力例)
動物→鳥類、哺乳類
鳥類→ペンギン、アヒル、スズメ
哺乳類→ニワトリ、リス
"""
import sys
class Node:
def __init__(self):
self.name = ''
self.childs = []
def parse(self, tokens, tok):
self.name = tok.name
for name in tok.names:
t = self.find_tok(tokens, name)
if t is None:
child = Node()
child.name = name
self.childs.append(child)
else:
child = Node()
child.parse(tokens, t)
self.childs.append(child)
return self
def find_tok(self, tokens, name):
for t in tokens:
if t.name == name:
return t
return None
def build_dump_nodes(self, dump_nodes, node, dep, parent, last, parent_last):
dnode = DumpNode()
dnode.name = node.name
dnode.dep = dep
dnode.parent = parent
dnode.last = last
dnode.parent_last = parent_last
dump_nodes.append(dnode)
for i, child in enumerate(node.childs):
self.build_dump_nodes(
dump_nodes=dump_nodes,
node=child,
dep=dep + 1,
parent=True,
last=i == len(node.childs) - 1,
parent_last=last,
)
def dump(self):
dump_nodes = []
self.build_dump_nodes(
dump_nodes=dump_nodes,
node=self,
dep=0,
parent=False,
last=True,
parent_last=True,
)
for dn in dump_nodes:
if dn.parent and dn.last:
if dn.parent_last:
print((dn.dep - 1) * ' ' + '└' + dn.name)
else:
print((dn.dep - 1) * '│' + '└' + dn.name)
elif dn.parent and not dn.last:
if dn.parent_last:
print((dn.dep - 1) * ' ' + '├' + dn.name)
else:
print((dn.dep - 1) * '│' + '├' + dn.name)
elif not dn.parent:
print(dn.name)
class DumpNode:
def __init__(self):
self.name = ''
self.dep = 0
self.parent = False
self.last = False
self.parent_last = False
class Token:
def __init__(self, name, names):
self.name = name
self.names = names
def tokenize():
tokens = []
for line in sys.stdin.readlines():
toks = line.split('→')
name = toks[0]
names = [c.strip() for c in toks[1].split('、')]
tokens.append(Token(name, names))
return tokens
def parse(tokens):
root = Node()
root.parse(tokens, tokens[0])
return root
def main():
tokens = tokenize()
root = parse(tokens)
root.dump()
return 0
if __name__ == '__main__':
sys.exit(main())
IiIiCuODl+ODreOCsOODqeODn+ODs+OCsOOBruOBiumhjOOCueODrCBQYXJ0MTcKaHR0cHM6Ly9tLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5oLm5ldC90ZXN0L3JlYWQuY2dpL3RlY2gvMTU4NDAzMTM2Ny8KCjU4NjoK44GK6aGMOiDjg4bjgq3jg4jjg7zjgavmnKjmp4vpgKDjgpLmj4/nlLvjgZvjgojjgIIKCuWFpeWKm+S+iykK5YuV54mp4oaS6bOl6aGe44CB5ZO65Lmz6aGeCumzpemhnuKGkuODmuODs+OCruODs+OAgeOCouODkuODq+OAgeOCueOCuuODoQrlk7rkubPpoZ7ihpLjg4vjg6/jg4jjg6rjgIHjg6rjgrkKIiIiCmltcG9ydCBzeXMKCgpjbGFzcyBOb2RlOgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHNlbGYubmFtZSA9ICcnCiAgICAgICAgc2VsZi5jaGlsZHMgPSBbXQoKICAgIGRlZiBwYXJzZShzZWxmLCB0b2tlbnMsIHRvayk6CiAgICAgICAgc2VsZi5uYW1lID0gdG9rLm5hbWUKCiAgICAgICAgZm9yIG5hbWUgaW4gdG9rLm5hbWVzOgogICAgICAgICAgICB0ID0gc2VsZi5maW5kX3Rvayh0b2tlbnMsIG5hbWUpCiAgICAgICAgICAgIGlmIHQgaXMgTm9uZToKICAgICAgICAgICAgICAgIGNoaWxkID0gTm9kZSgpCiAgICAgICAgICAgICAgICBjaGlsZC5uYW1lID0gbmFtZQogICAgICAgICAgICAgICAgc2VsZi5jaGlsZHMuYXBwZW5kKGNoaWxkKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgY2hpbGQgPSBOb2RlKCkKICAgICAgICAgICAgICAgIGNoaWxkLnBhcnNlKHRva2VucywgdCkKICAgICAgICAgICAgICAgIHNlbGYuY2hpbGRzLmFwcGVuZChjaGlsZCkKCiAgICAgICAgcmV0dXJuIHNlbGYKCiAgICBkZWYgZmluZF90b2soc2VsZiwgdG9rZW5zLCBuYW1lKToKICAgICAgICBmb3IgdCBpbiB0b2tlbnM6CiAgICAgICAgICAgIGlmIHQubmFtZSA9PSBuYW1lOgogICAgICAgICAgICAgICAgcmV0dXJuIHQKICAgICAgICByZXR1cm4gTm9uZQoKICAgIGRlZiBidWlsZF9kdW1wX25vZGVzKHNlbGYsIGR1bXBfbm9kZXMsIG5vZGUsIGRlcCwgcGFyZW50LCBsYXN0LCBwYXJlbnRfbGFzdCk6CiAgICAgICAgZG5vZGUgPSBEdW1wTm9kZSgpCiAgICAgICAgZG5vZGUubmFtZSA9IG5vZGUubmFtZQogICAgICAgIGRub2RlLmRlcCA9IGRlcAogICAgICAgIGRub2RlLnBhcmVudCA9IHBhcmVudAogICAgICAgIGRub2RlLmxhc3QgPSBsYXN0CiAgICAgICAgZG5vZGUucGFyZW50X2xhc3QgPSBwYXJlbnRfbGFzdAogICAgICAgIGR1bXBfbm9kZXMuYXBwZW5kKGRub2RlKQoKICAgICAgICBmb3IgaSwgY2hpbGQgaW4gZW51bWVyYXRlKG5vZGUuY2hpbGRzKToKICAgICAgICAgICAgc2VsZi5idWlsZF9kdW1wX25vZGVzKAogICAgICAgICAgICAgICAgZHVtcF9ub2Rlcz1kdW1wX25vZGVzLAogICAgICAgICAgICAgICAgbm9kZT1jaGlsZCwKICAgICAgICAgICAgICAgIGRlcD1kZXAgKyAxLAogICAgICAgICAgICAgICAgcGFyZW50PVRydWUsCiAgICAgICAgICAgICAgICBsYXN0PWkgPT0gbGVuKG5vZGUuY2hpbGRzKSAtIDEsCiAgICAgICAgICAgICAgICBwYXJlbnRfbGFzdD1sYXN0LAogICAgICAgICAgICApCgogICAgZGVmIGR1bXAoc2VsZik6CiAgICAgICAgZHVtcF9ub2RlcyA9IFtdCiAgICAgICAgc2VsZi5idWlsZF9kdW1wX25vZGVzKAogICAgICAgICAgICBkdW1wX25vZGVzPWR1bXBfbm9kZXMsCiAgICAgICAgICAgIG5vZGU9c2VsZiwKICAgICAgICAgICAgZGVwPTAsCiAgICAgICAgICAgIHBhcmVudD1GYWxzZSwKICAgICAgICAgICAgbGFzdD1UcnVlLAogICAgICAgICAgICBwYXJlbnRfbGFzdD1UcnVlLAogICAgICAgICkKICAgICAgICBmb3IgZG4gaW4gZHVtcF9ub2RlczoKICAgICAgICAgICAgaWYgZG4ucGFyZW50IGFuZCBkbi5sYXN0OgogICAgICAgICAgICAgICAgaWYgZG4ucGFyZW50X2xhc3Q6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoKGRuLmRlcCAtIDEpICogJ+OAgCcgKyAn4pSUJyArIGRuLm5hbWUpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHByaW50KChkbi5kZXAgLSAxKSAqICfilIInICsgJ+KUlCcgKyBkbi5uYW1lKQogICAgICAgICAgICBlbGlmIGRuLnBhcmVudCBhbmQgbm90IGRuLmxhc3Q6CiAgICAgICAgICAgICAgICBpZiBkbi5wYXJlbnRfbGFzdDoKICAgICAgICAgICAgICAgICAgICBwcmludCgoZG4uZGVwIC0gMSkgKiAn44CAJyArICfilJwnICsgZG4ubmFtZSkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoKGRuLmRlcCAtIDEpICogJ+KUgicgKyAn4pScJyArIGRuLm5hbWUpCiAgICAgICAgICAgIGVsaWYgbm90IGRuLnBhcmVudDoKICAgICAgICAgICAgICAgIHByaW50KGRuLm5hbWUpCgoKY2xhc3MgRHVtcE5vZGU6CiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgc2VsZi5uYW1lID0gJycKICAgICAgICBzZWxmLmRlcCA9IDAKICAgICAgICBzZWxmLnBhcmVudCA9IEZhbHNlCiAgICAgICAgc2VsZi5sYXN0ID0gRmFsc2UKICAgICAgICBzZWxmLnBhcmVudF9sYXN0ID0gRmFsc2UKCgpjbGFzcyBUb2tlbjoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lLCBuYW1lcyk6CiAgICAgICAgc2VsZi5uYW1lID0gbmFtZQogICAgICAgIHNlbGYubmFtZXMgPSBuYW1lcwoKCmRlZiB0b2tlbml6ZSgpOgogICAgdG9rZW5zID0gW10KICAgIGZvciBsaW5lIGluIHN5cy5zdGRpbi5yZWFkbGluZXMoKToKICAgICAgICB0b2tzID0gbGluZS5zcGxpdCgn4oaSJykKICAgICAgICBuYW1lID0gdG9rc1swXQogICAgICAgIG5hbWVzID0gW2Muc3RyaXAoKSBmb3IgYyBpbiB0b2tzWzFdLnNwbGl0KCfjgIEnKV0KICAgICAgICB0b2tlbnMuYXBwZW5kKFRva2VuKG5hbWUsIG5hbWVzKSkKICAgIHJldHVybiB0b2tlbnMKCgpkZWYgcGFyc2UodG9rZW5zKToKICAgIHJvb3QgPSBOb2RlKCkKICAgIHJvb3QucGFyc2UodG9rZW5zLCB0b2tlbnNbMF0pCiAgICByZXR1cm4gcm9vdAoKCmRlZiBtYWluKCk6CiAgICB0b2tlbnMgPSB0b2tlbml6ZSgpCiAgICByb290ID0gcGFyc2UodG9rZW5zKQogICAgcm9vdC5kdW1wKCkKICAgIHJldHVybiAwCgoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIHN5cy5leGl0KG1haW4oKSkK