J, 87 79 72 70 67 57 56 characters
'( ) 'charsub|.|:(+/\@('('&=-')'&=)(],~' '$~[)"0])1!:1[1
Takes input from the keyboard. Example:
'( ) '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
Explanation:
This explanation is based on the first version of my program:
|.|:('( ) 'charsub x)((' '$~{.@]),[{~{:@])"1(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
x=.1!:1[1
take input from keyboard and put it into x
for later
(('('&([:+/=)-')'&([:+/=))\,.i.@#)
creates a list of all indeces into the string (i.@#
) and stitches (,.
) it together with the result of the (('('&([:+/=)-')'&([:+/=))\
verb.
(('('&([:+/=)-')'&([:+/=))\
this verb is applied to all the prefixes of the string (so on input hello
it would apply to h
,he
,hel
,hell
, and hello
. It is a fork, which counts the number of open brackets ('('&([:+/=)
and then subtracts the number of close brackets ')'&([:+/=)
. This gives me list of indeces into the string and the level the character at that index should be at in the output. On simple input this gives me the following:
(('('&([:+/=)-')'&([:+/=))\,.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
this is a verb which takes the list I just generated and also the output of ('( ) 'charsub x)
(which just does a string replacement to replace all brackets with spaces in x
). It takes the tail of each item of the list {:@]
and uses it as an index into the string to get the character [{~{:@]
. Then it prefixes it ,
with the number of spaces as indicated by the head of each item in the list(' '$~{.@])
. On the previous example this gives me:
('( ) 'charsub x)((' '$~{.@]),[{~{:@])"1(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
(one(two(three)))
o
n
e
t
w
o
t
h
r
e
e
I then transpose the array |:
and reverse it |.
to get the desired output.
((1 2))))))))))3
should be invalid if negative heights are forbidden. \$\endgroup\$ – Cristian Lupascu Jul 12 '12 at 13:53