# coding: utf-8
require 'minitest/autorun'
F=
->i{w=i.index(?\n)+1
t=[i.index(/[^ _] *\n\z/)]
a=->x,c{(i[x]==c||i[x]==?_)&&t<<x}
((x=t.pop)&&(s=x-w;c=i[x])<?0?(a[s+1,?/];a[s,?\\]):c<?]?(a[s-1,?\\];a[s,?/]):c<?`?(a[x-1,?\\];a[x+1,?/]):a[s,?|]
i[x]=' ')while t!=[]
!i[/\S/]}
describe '#F' do
# Valid trees
#############
def test_young_tree
assert F['|
']
end
def test_valid_tree
assert F[' _
\/ /
\_/
|
|
']
end
def test_valid_italic_tree
assert F['
/ / \/
\ \____/
\/
/
/
']
end
def test_valid_cat_tree
assert F['
\___/
/ \
\___/
|
|
']
end
def test_valid_stair_tree
assert F['
__/
_/
/
']
end
def test_valid_old_tree
assert F['
____
\ ___
\ \/
\/\_____/
\/ \/
\__/
|
|
']
end
# Invalid trees
###############
def test_invalid_reachable_only_with_downward_route
refute F['
\/
\_______/
\__ /
| \_/
|
']
end
def test_invalid_multiple_roots
refute F['_']
end
def test_invalid_multiple_root_characters
refute F['\/
']
end
def test_invalid_multiple_roots
refute F['/\
']
end
def test_invalid_unreachable_part
refute F['
|
|
']
end
def test_invalid_unreachable_parts
refute F['
__/
/
|
']
end
def test_invalid_multiple_roots_2
refute F['
\____/
| |
']
end
def test_invalid_unreachable_parts_2
refute F['
_\__/
|
']
end
end
IyBjb2Rpbmc6IHV0Zi04CnJlcXVpcmUgJ21pbml0ZXN0L2F1dG9ydW4nCgpGPQotPml7dz1pLmluZGV4KD9cbikrMQp0PVtpLmluZGV4KC9bXiBfXSAqXG5cei8pXQphPS0+eCxjeyhpW3hdPT1jfHxpW3hdPT0/XykmJnQ8PHh9CigoeD10LnBvcCkmJihzPXgtdztjPWlbeF0pPD8wPyhhW3MrMSw/L107YVtzLD9cXF0pOmM8P10/KGFbcy0xLD9cXF07YVtzLD8vXSk6Yzw/YD8oYVt4LTEsP1xcXTthW3grMSw/L10pOmFbcyw/fF0KaVt4XT0nICcpd2hpbGUgdCE9W10KIWlbL1xTL119CgoKZGVzY3JpYmUgJyNGJyBkbwogICMgVmFsaWQgdHJlZXMKICAjIyMjIyMjIyMjIyMjCgogIGRlZiB0ZXN0X3lvdW5nX3RyZWUKICAgIGFzc2VydCBGWyd8CiddCiAgZW5kCgogIGRlZiB0ZXN0X3ZhbGlkX3RyZWUKICAgIGFzc2VydCBGWycgIF8gIApcLyAgLwogXF8vIAogIHwgIAogIHwgIAonXQogIGVuZAoKICBkZWYgdGVzdF92YWxpZF9pdGFsaWNfdHJlZQogICAgYXNzZXJ0IEZbJyAgICAgICAgIAovIC8gICAgXC8KXCBcX19fXy8gCiBcLyAgICAgIAogLyAgICAgICAKLyAgICAgICAgCiddCiAgZW5kCgogIGRlZiB0ZXN0X3ZhbGlkX2NhdF90cmVlCiAgICBhc3NlcnQgRlsnICAgICAgCiBcX19fLwogLyAgIFwKIFxfX18vCiAgIHwgIAogICB8ICAKJ10KICBlbmQKCiAgZGVmIHRlc3RfdmFsaWRfc3RhaXJfdHJlZQogICAgYXNzZXJ0IEZbJyAgICAgIAogICBfXy8KIF8vICAgCi8gICAgIAonXQogIGVuZAoKICBkZWYgdGVzdF92YWxpZF9vbGRfdHJlZQogICAgYXNzZXJ0IEZbJyAgICAgICAgICAgCl9fX18gICAgICAgCiAgXCAgX19fICAgCiBcIFwvICAgICAgCiAgXC9cX19fX18vCiBcLyAgXC8gICAgCiAgXF9fLyAgICAgCiAgICB8ICAgICAgCiAgICB8ICAgICAgCiddCiAgZW5kCgogICMgSW52YWxpZCB0cmVlcwogICMjIyMjIyMjIyMjIyMjIwoKICBkZWYgdGVzdF9pbnZhbGlkX3JlYWNoYWJsZV9vbmx5X3dpdGhfZG93bndhcmRfcm91dGUKICAgIHJlZnV0ZSBGWycgICAgICAgICAgClwvICAgICAgICAKIFxfX19fX19fLwogIFxfXyAgIC8gCiAgIHwgXF8vICAKICAgfCAgICAgIAonXQogIGVuZAoKICBkZWYgdGVzdF9pbnZhbGlkX211bHRpcGxlX3Jvb3RzCiAgICByZWZ1dGUgRlsnXyddCiAgZW5kCiAgCiAgZGVmIHRlc3RfaW52YWxpZF9tdWx0aXBsZV9yb290X2NoYXJhY3RlcnMKICAgIHJlZnV0ZSBGWydcLwonXQogIGVuZAogIAogIGRlZiB0ZXN0X2ludmFsaWRfbXVsdGlwbGVfcm9vdHMKICAgIHJlZnV0ZSBGWycvXAonXQogIGVuZAogCiAgZGVmIHRlc3RfaW52YWxpZF91bnJlYWNoYWJsZV9wYXJ0CiAgICByZWZ1dGUgRlsnIAp8CiAKfAonXQogIGVuZAoKICBkZWYgdGVzdF9pbnZhbGlkX3VucmVhY2hhYmxlX3BhcnRzCiAgICByZWZ1dGUgRlsnICAgIAogX18vCi8gICAKfCAgIAonXQogIGVuZAogIAogIGRlZiB0ZXN0X2ludmFsaWRfbXVsdGlwbGVfcm9vdHNfMgogICAgcmVmdXRlIEZbJyAgICAgIApcX19fXy8KIHwgIHwgCiddCiAgZW5kCgogIGRlZiB0ZXN0X2ludmFsaWRfdW5yZWFjaGFibGVfcGFydHNfMgogICAgcmVmdXRlIEZbJyAgICAgCl9cX18vCnwgICAgCiddCiAgZW5kCmVuZAo=