Telescopic Parentheses
x86 machine code, 39 34 33 30 29 bytes
00000000 68 c3 b8 07 31 ff be 82 00 b3 a0 ad 4e 3c 28 7c |h...1.......N<(||
00000010 f0 77 05 ab 01 df eb f3 29 df ab eb ee |.w......)....|
0000001d
x86 assembly for DOS, with some tricks:
org 100h
section .text
start:
; point the segment ES to video memory
; (c3 is chosen so that it doubles as a "ret")
push 0b8c3h
pop es
; di: output pointer to video memory
xor di,di
; si: input pointer from the command line
mov si,82h
; one row=160 bytes (assume bh=0, as should be)
mov bl,160
lop:
; read & increment si (assume direction flag clean)
; we read a whole word, so that later we have something nonzero to
; put into character attributes
lodsw
; we read 2 bytes, go back 1
dec si
; check what we read
cmp al,'('
; less than `(`: we got the final `\n` - quit
; (we jump mid-instruction to get a c3 i.e. a ret)
jl start+1
; more than `(`: assume we got a `)`
ja closed
; write a whole word (char+attrs), so we end
; one position on the right
stosw
; move down
add di,bx
; rinse & repeat
jmp lop
closed:
; move up
sub di,bx
; as above
stosw
jmp lop
Limitations:
- it always prints starting at the bottom of the screen, without erasing first; a
cls
before running is almost mandatory; - the colors are ugly; that's the consequence of recycling the next character as color attributes to save two bytes here and there;
- the code assumes
bh=0
and the direction flag clear on start, both undocumented; OTOH,bx
is explicitly set to zero in all DOS variants I saw (DosBox, MS-DOS 2, FreeDOS), and everywhere I tested the flags were already OK.
J, 32 28 bytes
This was a fun one.
0|:')(('&(i.-<:@+/\@i:){."0]
Explanation
This is how this solution works, including an explanation of how it has been golfed.
NB. Let a be a test case
a =. '((()())()(()(())()))'
NB. level alterations
_1 + ').(' i. a
1 1 1 _1 1 _1 _1 1 _1 1 1 _1 1 1 _1 _1 1 _1 _1 _1
NB. absolute levels
+/\ _1 + ').(' i. a
1 2 3 2 3 2 1 2 1 2 3 2 3 4 3 2 3 2 1 0
NB. adjusted levels
(+/\ _1 + ').(' i. a) - ')(' i. a
0 1 2 2 2 2 1 1 1 1 2 2 2 3 3 2 2 2 1 0
NB. take level from end of each item of a and transpose
|: a {."0~ _1 - (+/\ _1 + ').(' i. a) - ')(' i. a
( )
( )()( )
()() ()( )()
()
NB. code as a tacit verb
[: |: ] {."0~ _1 - ([: +/\ _1 + ').(' i. ]) - ')(' i. ]
NB. subtractions pulled into the prefix insert
[: |: ] {."0~ (')(' i. ]) - [: <:@+/\ ').(' i. ]
NB. i: instead of i. so we can use the same string constant
[: |: ] {."0~ (')((' i. ]) - [: <:@+/\ ')((' i: ]
NB. get rid of the caps
0 |: ] {."0~ (')((' i. ]) - ')((' <:@+/\@i: ]
NB. join the two usages of ')((' into a single dyadic phrase
0 |: ] {."0~ ')((' (i. - <:@+/\@i:) ]
NB. bond ')((' and flip arguments to {."0
0 |: ')(('&(i. - <:@+/\@i:) {."0 ]
Retina + Bash, 27 bytes (14 + 10 + 3 = 27)
This makes use of ANSI Escapes:
\(
(\e[B
\)
\e[A)
Equivalent to sed -e "s/(/(\\\e[B/g;s/)/\\\e[A)/g"
.
The \e[B
escape code means move cursor down one row, and the \e[A
means move cursor up one row, so this solution simply inserts those codes after and before the start and end of each nested pair of parentheses. Input is passed through STDIN.
You'll have to call it as printf $(Retina ...)
to see the output correctly.
Output
(((())))
(\e[B(\e[B(\e[B(\e[B\e[A)\e[A)\e[A)\e[A)
^C
amans:~ a$ printf "(\e[B(\e[B(\e[B(\e[B\e[A)\e[A)\e[A)\e[A)"
( )amans:~ a$
( )
( )
()
((()())()(()(())()))
(\e[B(\e[B(\e[B\e[A)(\e[B\e[A)\e[A)(\e[B\e[A)(\e[B(\e[B\e[A)(\e[B(\e[B\e[A)\e[A)(\e[B\e[A)\e[A)\e[A)
^C
amans:~ a$ printf "(\e[B(\e[B(\e[B\e[A)(\e[B\e[A)\e[A)(\e[B\e[A)(\e[B(\e[B\e[A)(\e[B(\e[B\e[A)\e[A)(\e[B\e[A)\e[A)\e[A)"
( )amans:~ a$
( )()( )
()() ()( )()
()