J, 87 79 72 70 67 57 56 caracteres
'( ) 'charsub|.|:(+/\@('('&=-')'&=)(],~' '$~[)"0])1!:1[1
Recebe entrada do teclado. Exemplo:
'( ) '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
Explicação:
Esta explicação é baseada na primeira versão do meu programa:
|.|:('( ) 'charsub x)((' '$~{.@]),[{~{:@])"1(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
x=.1!:1[1
pegue a entrada do teclado e coloque-a x
para mais tarde
(('('&([:+/=)-')'&([:+/=))\,.i.@#)
cria uma lista de todos os indeces na string ( i.@#
) e costura ( ,.
) junto com o resultado do (('('&([:+/=)-')'&([:+/=))\
verbo.
(('('&([:+/=)-')'&([:+/=))\
este verbo é aplicado a todos os prefixos do string (assim por diante entrada hello
seria aplicável para h
, he
, hel
, hell
, e hello
. É um garfo , que conta o número de suportes abertos ('('&([:+/=)
e, em seguida, subtrai o número de suportes de perto ')'&([:+/=)
. Isso me dá lista de indeces na string e no nível em que o caractere nesse índice deve estar na saída.Em entradas simples, isso me dá o seguinte:
(('('&([:+/=)-')'&([:+/=))\,.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
este é um verbo que pega a lista que acabei de gerar e também a saída de ('( ) 'charsub x)
(que apenas substitui uma string para substituir todos os colchetes por espaços x
). Ele pega o final de cada item da lista {:@]
e o usa como um índice na string para obter o caractere [{~{:@]
. Em seguida, o prefixa ,
com o número de espaços, conforme indicado pelo cabeçalho de cada item na lista (' '$~{.@])
. No exemplo anterior, isso me dá:
('( ) 'charsub x)((' '$~{.@]),[{~{:@])"1(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
(one(two(three)))
o
n
e
t
w
o
t
h
r
e
e
Transponho a matriz |:
e a inverto |.
para obter a saída desejada.
((1 2))))))))))3
deve ser inválida se alturas negativas forem proibidas.