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
має бути недійсним, якщо заборонені висоти заборонені.