J, 87 79 72 70 67 57 56 символів
'( ) 'charsub|.|:(+/\@('('&=-')'&=)(],~' '$~[)"0])1!:1[1
Вводиться з клавіатури. Приклад:
'( ) 'charsub|.|:(+/\@('('&=-')'&=)(],~' '$~[)"0])1!:1[1
((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))
4 5 cherries woohoo
1 2 3 moo lik e
i
Пояснення:
Це пояснення ґрунтується на першій версії моєї програми:
|.|:('( ) 'charsub x)((' '$~{.@]),[{~{:@])"1(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
x=.1!:1[1візьміть дані з клавіатури та вкладіть її на xпотім
(('('&([:+/=)-')'&([:+/=))\,.i.@#)створює список усіх відмінків у рядок ( i.@#) та прошиває ( ,.) разом із результатом (('('&([:+/=)-')'&([:+/=))\дієслова.
(('('&([:+/=)-')'&([:+/=))\це дієслово застосовується до всіх префіксам рядки (так на вході helloбуло б застосувати до h, he, hel, hell, і hello. Він являє собою вилку , яка підраховує кількість відкритих дужок , ('('&([:+/=)а потім віднімає число близьких дужок ')'&([:+/=). Це дає мені список індексів у рядку та рівня, на якому символ у цьому індексі має бути на виході. На простому введенні це дає мені таке:
(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
(one(two(three)))
1 0
1 1
1 2
1 3
2 4
2 5
2 6
2 7
3 8
3 9
3 10
3 11
3 12
3 13
2 14
1 15
0 16
((' '$~{.@]),[{~{:@])"1це дієслово, яке бере список, який я тільки що створив, а також результат ('( ) 'charsub x)(який просто робить заміну рядка для заміни всіх дужок пробілами в x). Він бере хвіст кожного елемента списку {:@]і використовує його як індекс у рядку для отримання символу [{~{:@]. Потім він префіксує його ,кількістю пробілів, як зазначено заголовком кожного елемента в списку (' '$~{.@]). На попередньому прикладі це дає мені:
('( ) 'charsub x)((' '$~{.@]),[{~{:@])"1(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
(one(two(three)))
o
n
e
t
w
o
t
h
r
e
e
Потім перекладаю масив |:і повертаю його назад, |.щоб отримати бажаний вихід.
((1 2))))))))))3має бути недійсним, якщо заборонені висоти заборонені.