J, 87 79 72 70 67 57 56 caracteres
'( ) 'charsub|.|:(+/\@('('&=-')'&=)(],~' '$~[)"0])1!:1[1
Toma entrada del teclado. Ejemplo:
'( ) '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
Explicación:
Esta explicación se basa en la primera versión de mi programa:
|.|:('( ) 'charsub x)((' '$~{.@]),[{~{:@])"1(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
x=.1!:1[1tomar entrada del teclado y ponerla xpara más tarde
(('('&([:+/=)-')'&([:+/=))\,.i.@#)crea una lista de todas las indeces en la cadena ( i.@#) y las ,.une ( ) junto con el resultado del (('('&([:+/=)-')'&([:+/=))\verbo.
(('('&([:+/=)-')'&([:+/=))\este verbo se aplica a todos los prefijos de la cadena (por lo que en la entrada hellose aplicaría a h, he, hel, hell, y hello. Se trata de un tenedor , que cuenta el número de tramos abiertos ('('&([:+/=)y luego se resta el número de tramos estrechos ')'&([:+/=). Esto me da la lista de indeces en la cadena y el nivel en el que el carácter en ese índice debe estar en la salida. En una entrada simple esto me da lo siguiente:
(('('&([:+/=)-')'&([:+/=))\,.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
((' '$~{.@]),[{~{:@])"1Este es un verbo que toma la lista que acabo de generar y también la salida de ('( ) 'charsub x)(que solo reemplaza una cadena para reemplazar todos los corchetes con espacios x). Toma la cola de cada elemento de la lista {:@]y lo usa como índice en la cadena para obtener el carácter [{~{:@]. Luego lo antepone ,con el número de espacios como lo indica el encabezado de cada elemento en la lista (' '$~{.@]). En el ejemplo anterior esto me da:
('( ) 'charsub x)((' '$~{.@]),[{~{:@])"1(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
(one(two(three)))
o
n
e
t
w
o
t
h
r
e
e
Luego transpongo la matriz |:y la invierto |.para obtener la salida deseada.
((1 2))))))))))3debe ser inválida si las alturas negativas están prohibidas.