텔레스코픽 괄호


79

비어 있고 올바르게 균형 잡힌 괄호로 구성된 문자열을 고려하십시오.

(()(()())()((())))(())

우리는 각 괄호 쌍이 축소 된 망원경 구조 의 고리를 나타낸다고 상상할 수 있습니다 . 망원경을 확장 해 봅시다 :

(                )(  )
 ()(    )()(    )  ()
    ()()    (  )
             ()

그것을 보는 또 다른 방법은 깊이 n 의 괄호 가 가로 위치를 유지하면서 선 n 으로 이동한다는 것 입니다.

당신의 임무는 이러한 일련의 균형 괄호를 사용하고 확장 버전을 생성하는 것입니다.

STDIN (또는 가장 가까운 해당), 명령 행 인수 또는 함수 매개 변수를 통해 입력을 받고 STDOUT (또는 가장 가까운 동등한), 리턴 값 또는 함수 (out) 매개 변수를 통해 출력을 생성하는 프로그램 또는 함수를 작성할 수 있습니다.

입력 문자열이 유효하다고 가정 할 수 있습니다. 즉, 정확하게 균형이 잡힌 괄호로만 구성됩니다.

각 줄에 후행 공백을 인쇄 할 수 있지만 필요 이상의 선행 공백은 인쇄 할 수 없습니다. 전체적으로 줄은 입력 문자열 길이의 두 배보다 길어서는 안됩니다. 선택적으로 단일 후행 줄 바꿈을 인쇄 할 수 있습니다.

위의 예제 외에도 몇 가지 테스트 사례가 더 있습니다 (입력과 출력은 빈 줄로 구분됨).

()

()
(((())))

(      )
 (    )
  (  )
   ()
()(())((()))(())()

()(  )(    )(  )()
   ()  (  )  ()
        ()
((()())()(()(())()))

(                  )
 (    )()(        )
  ()()    ()(  )()
             ()

관련 도전 :

  • Topographic Strings- 이 과제에서 본질적으로 출력의 보완 물을 생성하도록 요청합니다.
  • 코드 설명 Formatter 는 최근 PhiNotPi에 의해 게시 된이 과제에 대한 아이디어의 광범위한 일반화입니다. (실제로, PhiNotPi의 그의 아이디어에 대한 원래의 설명은이 도전에 영감을주었습니다.)

리더 보드

허, 여기에는 많은 참여가 있었으므로 여기에는 정규 리더 보드와 언어 별 수상자 개요를 생성하는 스택 스 니펫이 있습니다.

답변이 표시되도록하려면 다음 마크 다운 템플릿을 사용하여 헤드 라인으로 답변을 시작하십시오.

# Language Name, N bytes

N제출물의 크기는 어디에 있습니까 ? 당신이 당신의 점수를 향상시킬 경우에, 당신은 할 수 있습니다 를 통해 눈에 띄는에 의해, 헤드 라인에 오래된 점수를 유지한다. 예를 들어 :

# Ruby, <s>104</s> <s>101</s> 96 bytes


17
다른 제목 : 문자열을 De-Lisp-ify하십시오. : P
Alex A.

1
출력 색상에 제한이 있습니까?
Matteo Italia

1
@ MartinBüttner : 더 신경 쓰지 않는 방법을 찾았습니다. 내 이전 아이디어가 청록색 위에 파란색으로 깜박이 는 닫힌 괄호를 남기고 바이트를 깎았을 것입니다 ... :-)
Matteo Italia

8
@MatteoItalia 오, 이런 일이 일어나지 않아서 다행입니다. ;)
Martin Ender 2016

12
@MatteoItalia : 해당 버전을 게시하십시오! 볼만한 가치가 있습니다.
user2357112

답변:


8

CJam, 17 16 15 바이트

0000000: 72 3a 69 22 28 0b 20 9b 41 29 22 53 2f 66 3d     r:i"(. .A)"S/f=

소스 코드에는 인쇄 할 수없는 문자 VT (0x0b)와 CSI (0x9b)가 포함되어 있으므로 위의 뒤집을 수있는 xxd 덤프입니다.

마찬가지로 이 답변 , 그것을 사용하여 ANSI 이스케이프 시퀀스를 ,뿐만 아니라 수직 탭을 사용하고는 사용하지 않는 것이 직접 제어 문자를 인쇄 의 printf를 .

이를 위해서는 대부분의 비 Windows 터미널 에뮬레이터를 포함하는 지원 비디오 텍스트 터미널이 필요합니다.

시운전

쉘 변수 LANG 와 터미널 에뮬레이터의 인코딩을 ISO 8859-1로 설정해야합니다. 전자는 실행함으로써 달성됩니다

$ LANGsave="$LANG"
$ LANG=en_US

또한 실제 코드를 실행하기 전에 프롬프트를 비활성화하고 화면을 지 웁니다.

$ PS1save="$PS1"
$ unset PS1
$ clear

이렇게하면 출력이 올바르게 표시됩니다.

echo -n '()(())((()))(())()' | cjam <(base64 -d <<< cjppIigLIJtBKSJTL2Y9)
()(  )(    )(  )()
   ()  (  )  ()
        ()

LANG 와 프롬프트 를 복원하려면 다음을 실행하십시오.

$ LANG="$LANGsave"
$ PS1="$PS1save"

작동 원리

우리는 각 후 수직 탭을 삽입 ( 아래 커서와 바이트 시퀀스로 이동합니다 9B (41) ( "\x9bA"각 이전을) ) 커서를 위로 이동합니다.

r         e# Read a whitespace-separated token from STDIN.
:i        e# Replace each character by its code point.
          e#   '(' -> 40, ')' -> 41
"(. .A)"  e# Push the string "(\v \x9bA)".
S/        e# Split at spaces into ["(\v" "\x9bA)"].
f=        e# Select the corresponding chunks.
          e# Since arrays wrap around in CJam, ["(\v" "\x9bA)"]40= and 
          e# ["(\v" "\x9bA)"]41= select the first and second chunk, respectively.

49

x86 기계 코드, 39 34 33 30 29 바이트

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

DOS 용 x86 어셈블리, 몇 가지 요령 :

    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

제한 사항 :

  • 항상 지우지 않고 화면 하단에서 시작하여 인쇄합니다. cls실행하기 전에 거의 필수입니다;
  • 색이 못 생겼다. 그것은 다음 문자를 색 속성으로 재활용하여 여기 저기 2 바이트를 절약 한 결과입니다.
  • 코드는 bh=0문서화되지 않은 것으로 시작시 방향 플래그를 지우고 가정합니다 . OTOH bx는 내가 본 모든 DOS 변형 (DosBox, MS-DOS 2, FreeDOS)에서 명시 적으로 0으로 설정되었으며 플래그를 테스트 한 모든 곳에서 이미 OK였습니다.

여기에 이미지 설명을 입력하십시오


이것을 확인했습니다. 예, 작동합니다. 정말로해야합니까 cld?
FUZxxl

@FUZxxl : DosBox에서는 그것 없이도 잘 작동하지만 소스를 보면 플래그가 DOS와 TRS에서 발생했던 모든 것으로부터 보존된다고 말하므로 안전하게 재생해야 할 것입니다. 어쨌든, 그것은 단지 1 바이트 일 것입니다. 실제 지불은 큰 (= 4 바이트) add/ 중 적어도 하나를 죽이는 것 sub입니다.
Matteo Italia

흠 ... 정말 모르겠습니다.
FUZxxl

로 변경할 loploop있습니까?
mbomb007

@ mbomb007 : 아마도? 레이블과 어셈블리 명령 으로 nasm명확하게 구분 되는지 확실하지 않으므로 다른 사람이하는 것처럼 작성 합니다. looplooplop
Matteo Italia

28

J, 32 28 바이트

재미있었습니다.

0|:')(('&(i.-<:@+/\@i:){."0]

설명

이것이 골프화 방법에 대한 설명을 포함하여이 솔루션의 작동 방식입니다.

   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 ]

1
아주 좋아요! 해결책은 훌륭한 부분들로 가득합니다!
randomra

1
(보통 경험이없는 사용자도 시도해 볼 수 있도록 함수 호출 예제를 추가합니다.)
randomra

이 솔루션은 내 머리의 상처를 만든다:')
닉 하틀리에게

@QPaysTaxes 나는 이것을 칭찬으로 받아들입니다.
FUZxxl

@FUZxxl입니다. 또한 답에 나타나는 일련의 문자를 기반으로 말장난입니다.
Nic Hartley

15

C, 150 바이트

t;f(char*c){char l=strlen(c)+1,o[l*l],*A=o,m=0;for(t=1;t<l*l;t++)o[t-1]=t%l?32:10;for(t=-1;*c;c++)A++[l*(*c-41?++t>m?m=t:t:t--)]=*c;A[m*l]=0;puts(o);}

이것은 골프 에 미친 재미 이었다 . 나는 아직도 내가 끝났다고 확신하지 못한다.

f문자열을 입력으로 사용하고 stdout으로 출력 하는 단일 함수를 정의합니다 .

코드를 한 줄씩 살펴 보겠습니다 :

/* t will represent the current depth of a parentheses. It must be an int. */
t;
f(char*c){
    //Our variables:
    char l=strlen(c)+1,    //The length of each row of output, including newlines
         o[l*l],           //The output string. It's way larger than it needs to be.
         *A=o,             //We need another pointer to keep track of things.
         m=0;              //The maximum depth recorded thus far.

    for(t=1;t<l*l;t++)     //For each character in our output...
        o[t-1]=t%l?32:10;  //If it's at the end of a line, make it '\n'. Else, ' '.
    for(t=-1;*c;c++)       //While we have an input string...
        //Perhaps a personal record for ugliest warning-less line...
        A++[l*(*c-41?++t>m?m=t:t:t--)]=*c;
    /* 
        A breakdown:
        A++        --> Go to the next *column* of output, after writing. 
                   --> There will only ever be one parentheses per output column.
        [l*(...)]  --> A[l*X] is the character in the current column at depth X.
        (*c-41?    --> If the character is a '('...    
        ++t>m?     --> Increment t *before* we write it. If this is a new highest depth
        m=t:       --> Set m to t, and set the whole expression to t.
        t:         --> If it's not a new highest depth, don't set m.
        t--)       --> If the character was a ')', decrement t *after* we write it.
        =*c        --> Write our output character to whatever the input read.
    */    

    A[m*l]=0; //The last character of the maximum-depth line should be null terminated.
    puts(o);  //Output!
}

궁금한 점이 있으면 답변 드리겠습니다.

온라인 테스트 프로그램을 사용해보십시오 !


"char l = strlen (c) +1, o [l * l]"은 변수 크기 배열을 정의 할 수 없기 때문에 유효하지 않습니다.하지만 15 년이 지난 지금 C.
Sparr

@Sparr 내 컴파일러는 경고조차하지 않습니다. 나는 이것이 C99에서 "공식적으로"표준이라고 생각합니다. 이에 대한 참조를 찾으려고 노력할 것입니다.
BrainSteel

1
@Sparr 다음 은 참조입니다.
BrainSteel

감사. 이와 관련하여 15 년 전 (몇 몇 주 또는 몇 년)에 상황이 바뀌는 것 같습니다.)
Sparr

1
그것은 @CoolGuy 만의 후속 호출에 것 f, m이것은 불법 "환경을 파괴"으로 간주 0으로 재설정 할 것이다 여기 .
BrainSteel

15

Retina + Bash, 27 바이트 (14 + 10 + 3 = 27)

이것은 ANSI Escapes를 사용합니다 :

\(
(\e[B
\)
\e[A)

에 해당합니다 sed -e "s/(/(\\\e[B/g;s/)/\\\e[A)/g". \e[B이스케이프 코드는 하나 개의 행을 커서를 아래로 이동을 의미하고, \e[A수단은 하나 개의 행을 커서를 이동, 그래서이 솔루션은 단순히 후 괄호 중첩 된 각 쌍의 시작 및 종료하기 전에 해당 코드를 삽입합니다. 입력은 STDIN을 통해 전달됩니다.

printf $(Retina ...)출력을 올바르게 보려면 이를 호출해야 합니다.

산출

(((())))
(\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$ 
 (    )()(        )
  ()()    ()(  )()
             ()

1
글쎄, 나쁘지 않아! 필요 없는 특정 터미널을 가리킬 수 있다면 printf좋을 것입니다. 그렇지 않으면 | printf바이트 수 에 추가 하는 것이 공정하다고 생각합니다 .
Martin Ender

@ MartinBüttner printf $()또는 이어야합니다 printf $(Retina ).
jimmy23013

1
레티 나가 뭐에요?
FUZxxl

2
@FUZxxl 내 정규식 기반 프로그래밍 언어입니다. GitHub를 참조하십시오 .
Martin Ender

2
\e더하기 printf? 대체 문자에 제어 문자를 넣을 수 있습니다.
Dennis

15

TI-BASIC, 69 60 56 55 바이트

TI-83 + / 84 + 계산기 제품 군용이지만 84+ C 실버 에디션으로 작성되었습니다.

VAT + size 정보가 포함되어 프로그램이 더 큰 계산으로 표시됩니다. 또한 여기에는 56 자 이상이 있습니다. 56 바이트 인 이유는 하나 이상의 문자 인 모든 명령이 1 또는 2 바이트 크기의 토큰으로 압축되기 때문입니다.

Input Str1
1→B
For(A,1,length(Str1
sub(Str1,A,1→Str2
Ans="(
Output(B+Ans,A,Str2
B-1+2Ans→B
End

thomas-kwa 덕분에 다른 바이트를 깎았습니다 ! (또한 그에게서 60에서 56으로 점프했습니다.)


4
아아, 내 첫 프로그래밍 언어. 향수에 감사드립니다, 하하
Alex Pritchard

1
고등학교 수학 수업을 위해 여전히 TI를 프로그래밍하고 있으며, 시험 및 과제에 대해 계산할 수있는 수식이 내장되어있어 매우 유용합니다.
Elias Benevedes

1
주위를 이동하면 cos(piAns트릭을 사용하여 다른 바이트를 저장할 수 있습니다 .
lirtosiast

9

파이썬 2, 115 바이트

def f(L,n=0,O=()):
 for c in L:n-=c>"(";O+=" "*n+c,;n+=c<")"
 for r in map(None,*O):print"".join(c or" "for c in r)

like를 호출 f("((()())()(()(())()))")하면 STDOUT으로 출력됩니다.

설명

우리는로 시작합니다 n = 0. 입력 줄의 각 문자에 대해 :

  • 문자가 (인 경우 n공백을 추가 한 다음 증가시킵니다.n
  • 숯불이 경우 ), 우리는 감소 n후 앞에 추가 n공간을

그런 다음 결과가 압축되어 인쇄됩니다. 가장 짧은 요소 zip의 길이와 일치 하는 Python의 zip은 다음과 같습니다.

>>> zip([1, 2], [3, 4], [5, 6, 7])
[(1, 3, 5), (2, 4, 6)]

가장 긴 요소 의 길이를 채우려면 일반적으로 itertools.zip_longest( izip_longest)를 사용 합니다.zip

>>> import itertools
>>> list(itertools.izip_longest([1, 2], [3, 4], [5, 6, 7]))
[(1, 3, 5), (2, 4, 6), (None, None, 7)]

그러나 Python 2에서는이 동작을 매핑하여 시뮬레이션 할 수 있습니다 None.

>>> map(None, [1, 2], [3, 4], [5, 6, 7])
[(1, 3, 5), (2, 4, 6), (None, None, 7)]

파이썬 3, 115 바이트

L,d,*O=input(),0
for i,c in enumerate(L):b=c>"(";O+="",;O[d-b]=O[d-b].ljust(i)+c;d-=b*2-1
for l in O:l and print(l)

압축하지 않고으로 적절히 패딩하십시오 ljust. 이것은 골프 잠재력을 가지고있는 것 같습니다.


8

R, 151127

S=strsplit(scan(,""),"")[[1]];C=cumsum;D=c(C(S=="("),0)-c(0,C(S==")"));for(j in 1:max(D)){X=S;X[D!=j]=' ';cat(X,sep='',fill=T)}

들여 쓰기 및 줄 바꿈 :

S=strsplit(scan(,""),"")[[1]]
C=cumsum
D=c(C(S=="("),0)-c(0,C(S==")"))
for(j in 1:max(D)){
    X=S
    X[D!=j]=' '
    cat(X,sep='',fill=T)
    }

용법:

> S=strsplit(scan(,""),"")[[1]];C=cumsum;D=c(C(S=="("),0)-c(0,C(S==")"));for(j in 1:max(D)){X=S;X[D!=j]=' ';cat(X,sep='',fill=T)}
1: ()(())((()))(())()
2: 
Read 1 item
()(  )(    )(  )()
   ()  (  )  ()   
        ()        
> S=strsplit(scan(,""),"")[[1]];C=cumsum;D=c(C(S=="("),0)-c(0,C(S==")"));for(j in 1:max(D)){X=S;X[D!=j]=' ';cat(X,sep='',fill=T)}
1: ((()())()(()(())()))
2: 
Read 1 item
(                  )
 (    )()(        ) 
  ()()    ()(  )()  
             ()     

또한, 하나의 문자의 벡터로 분리, 표준 입력으로 문자열을 판독의 누적 합을 계산 (하고 ), 이에 따라 각각의 괄호 "레벨"컴퓨팅 (래그 함께) 후자와 전자를 substracts. 그런 다음 각 레벨마다 해당 괄호 또는 공백으로 stdout으로 인쇄합니다.

상당히 단축시켜 준 @MickyT에게 감사드립니다!


2
+1 멋지고 우아한 솔루션. 당신은 대체하여 6을 절약 할 수 있습니다 for(i in n)cat(ifelse(D[i]-j," ",S[i]));cat("\n")X=S;X[which(D!=j)]=' ';cat(X,sep='',fill=T). 그런 다음 n실제로 필요하지는 않지만 cumsum 부분을 약간 변경해야합니다. D=c(C(S=="("),0)-c(0,C(S==")"));
낮추기

@MickyT 와우 감사합니다! 그것을 생각하지 않았다. which여기서 실제로 필요하지는 않습니다 ( D!=j이미 색인을 허용하는 부울 벡터입니다). 에 fill대한 논쟁 을 몰랐 cat습니다. 멋진 요령입니다! 놀랍도록 24 명의 문자를 줄여 주셔서 감사합니다 !!
plannapus

8

C, 58 53 52 51 49 바이트

커서 이스케이프 시퀀스를 사용하여 커서 위치를 이동합니다.

f(char*s){while(*s)printf(*s++&1?"\e[A)":"(\v");}

gcc 또는 지원하는 다른 컴파일러를 사용하지 않는 경우 총 2 바이트를 추가 \e할 수 있습니다 \x1B. \e[A커서를 한 행 위로 이동하고 커서를 한 행 \e[B아래로 이동합니다. 그것은 사용하기 필요는 없습니다 \e[B가 ASCII 수직 탭 문자를 사용하는 두 바이트 짧다으로 한 행을 아래로 이동 0xB또는 \v.

입력 문자열이 너무와 문자의 패리티 검사 만 (밸런스) 괄호 구성하는 질문에서, 가정 &1, 구별하기에 충분 (하고 ).


7

핍, 53 바이트

은 내 발명의 코드 골프 언어입니다. 첫 번째 버전은 토요일에 출판되었으므로 공식적으로 볼 수 있습니다! 아래의 솔루션은 골프 언어가 진행됨에 따라 크게 경쟁적이지는 않지만 zip 및 max와 같은 것을 아직 구현하지 않았기 때문입니다.

z:{aEQ'(?++v--v+1}MaW(o:{z@++v=i?as}Ma)RMs{Pov:-1++i}

명령 줄 인수로 괄호 문자열을 예상합니다.

"골프되지 않은"버전 :

z:{
   a EQ '( ?
    ++v
    --v+1
  } M a
W (o:{
      z @ ++v = i ?
       a
       s
     } M a
  ) RM s
{
 P o
 v:-1
 ++i
}

설명:

대부분의 골프 언어와 달리 Pip은 중위 연산자와 함께 필수적이므로 구문은 C 및 그 파생어에 다소 가깝습니다. 또한 기능 및 배열 기반 프로그래밍에서 아이디어를 얻습니다. 추가 문서는 저장소를 참조하십시오.

프로그램은 먼저 z함수를 입력 문자열에 매핑하여 깊이 목록 (저장 )을 생성 합니다 a. 글로벌 변수 v는 현재 레벨을 추적합니다. a-gPip의 변수 는 함수 로컬 변수이지만 h-z전역 변수 입니다. v-1로 사전 초기화 되었기 때문에 편리합니다.

다음으로, W생성 된 라인이 모든 공백으로 구성 될 때까지 hile 루프를 사용하여 각 라인을 생성하고 인쇄합니다. v이제 열과 i행에 사용됩니다. {z@++v=i?as}원래 입력 문자열에 반복적으로 맵핑 되는 함수는 현재 i행이 현재 괄호가있는 행 과 일치 하는지 테스트합니다 ( z목록에 저장 됨 ). 그렇다면 괄호 ( a)를 사용하십시오 . 그렇지 않으면 s(공간에 사전 초기화 됨)을 사용하십시오. 최종 결과는 각 반복 o에서 출력의 다음 행에 해당하는 문자 목록이 지정됩니다.

루핑을 계속해야하는지 테스트하기 위해 o모든 공백 RM'd가 비어 있는지 확인합니다 . 그렇지 않은 경우 인쇄하여 (기본적으로 CJam에서와 같이 모든 항목을 연결 함) 열 번호를 -1로 재설정하고 행 번호를 늘리십시오.

(재미있는 사실 : 처음에는 51 바이트 솔루션이 있었지만 통역사에 버그가 생겨서 작동하지 않았습니다.)


7

Pyth, 31 바이트

VzJs.e?YqN-/<zk\(/<zhk\)dzI-JdJ

온라인으로 사용해보십시오.

-/<zk\(/<zhk\): 현재 문자 위치에 적합한 레벨을 찾습니다.

?YqN-/<zk\(/<zhk\)d: 적절한 레벨이 현재 레벨이 아닌 경우 공백, 그렇지 않으면 현재 문자.

Js.e?YqN-/<zk\(/<zhk\)dz: 문자열을 생성하여에 저장하십시오 J.

I-JdJ: J모든 공간이 아닌 경우 인쇄하십시오.

Vz: 루프 z타임.


6

GNU Bash + coreutils + 들여 쓰기, 135

eval paste "`tr '()' {}|indent -nut -i1 -nbap|sed 's/.*/<(fold -1<<<"&")/'|tr '
' \ `"|expand -t2|sed 'y/{}/()/;s/\(.\) /\1/g;s/ \+$//'

STDIN / STDOUT을 통한 입출력 :

$ ./telescopic.sh <<< "(()(()())()((())))(())"
(                )(  )
 ()(    )()(    )  ()
    ()()    (  )
             ()
$ 

indent무거운 작업을 대부분 수행하지만 괄호 대신 괄호로 작업해야합니다. 나머지는 이 답변수정 하여의 출력을 바꿉니다 indent.


5

파이썬 2, 92

def f(s,i=0,z=''):
 for x in s:b=x>'(';z+=[' ',x][i==b];i-=2*b-1
 if'('in z:print z;f(s,i-1)

한 줄씩 인쇄합니다. 주어진 행 번호 i(실제로 그 부정)에 대해 입력 문자열을 거치고 at depth 의 문자 만 포함 s하는 새 문자열 z을 만듭니다 . 이것은 증가 시키거나 감소시키는에 의해 수행되는 현재의 깊이를 추적 할 때 현재 문자가 추가 되는 괄호 유형에 따라 조정하고, 그렇지 않으면 공간을 추가.siii0

그런 다음 i현재 줄이 모두 공백이 아닌 한 인쇄하고 다음 줄로 돌아갑니다 . 파 렌스가 균형을 이루기 때문에 i애프터 루프는 시작과 동일합니다.

파이썬 3은에 대한 문자를 제외하고 동일합니다 print(z).


5

부정 행위 :( Retina + TeX, N bytes 부정 행위 :(

MathJax 또는 다른 SEX를 사용하여 출력을 렌더링 (?)하는 경우에만 작동합니다.

\(
({
\)
})
\{\(
_{(

각 줄은 다른 파일에 있어야하지만 Retina -e "\(" -e "({" -e "\)" -e "})" -e "\{\(" -e "_{("(또는 동등한 sed 명령 sed -e "s/(/({/g;s/)/})/g;s/{(/_{(/g") 을 사용하여 테스트 할 수 있습니다 . 입력은 STDIN을 통해 전달됩니다.

이것은 각 괄호 쌍의 내용을 중괄호로 묶고 그 안에있는 모든 항목을 첨자 화하여 작동합니다.

산출

(((())))
(_{(_{(_{({})})})})

()(())((()))(())()
({})(_{({})})(_{(_{({})})})(_{({})})({})

((()())()(()(())()))
(_{(_{({})({})})({})(_{({})(_{({})})({})})})

TeX 출력


1
Retina를 사용했다고 생각합니다. 이것은 상자 밖에서 좋은 생각이지만 출력의 모양이 아닙니다. ;) 특히 이것은 대안적인 공식을 위반한다. "이것을 보는 또 다른 방법은 깊이 n의 괄호가 수평 위치를 유지하면서 라인 n으로 이동한다는 것이다." 나는 매우하지만 순수, 규칙 준수 망막 솔루션에 깊은 인상을 거라고하고 있습니다 그것을 위해 현상금을 손. ;)
Martin Ender

In total the lines must not be longer than twice the length of the input string. 라인 2를 (\,{라인 4로 변경 }\,)하면 출력이 이것에 적합 함 을 의미합니다 (수직 깊이는 여전히 잘못되었지만 : ()
user22723

글쎄, 나는 규칙을 준수하는 솔루션을 만들 수 있었다
:)

1
좋은 작업. 나는 당신이 지금 치타 티 답변을 삭제할 수 있음을 의미한다고 생각합니다. ;)
Martin Ender

5

자바 232 226 224 222 바이트

골프 버전 :

int i,j,k,l,m,a[];void f(String s){a=new int[s.length()];j=a.length;for(k=0;k<j;){a[k]=s.charAt(k++)<41?i++:--i;m=m<i?i:m;}for(k=0;k<m;k++)for(l=0;l<j;)System.out.print(k==a[l++]?i++%2<1?'(':l==j?")\n":')':l==j?'\n':' ');}

긴 버전 :

int i, j, k, l, m, a[];
void f(String s) {
    a = new int[s.length()];
    j = a.length;
    for (k = 0; k < j;) {
        a[k] = s.charAt(k++) < 41 ? i++ : --i;
        m = m < i ? i : m;
    }
    for (k = 0; k < m; k++)
        for (l = 0; l < j;)
            System.out.print(k == a[l++] ? (i++ % 2 < 1 ? '(' : (l == j ? ")\n" : ')')) : (l == j ? '\n':' '));
}

입력 문자열을 먼저 분석하여 카운터를 더하거나 빼기 위해 "("및 ")"를 찾고 괄호 아래로 얼마나 멀리 내려 가야하는지 결정하는 값을 저장하고 가장 깊은 곳까지 깊게 추적합니다. 그런 다음 배열을 분석합니다. 값이 작은 괄호가 먼저 인쇄되고 최대 값에 도달 할 때까지 한 줄씩 계속 인쇄됩니다.

아마 나중에 이것을 골프하는 방법을 찾을 것입니다.


5

자바 스크립트 / ES6, 97 자

f=s=>{for(n in s){m=o=d='';for(c of s)o+=n==(c<')'?d++:--d)?c:' ',m=m<d?d:m;n<m&&console.log(o)}}

용법

f("(()(()())()((())))(())")

설명

fn=str=>{                          // accepts string of parenthesis
  for(line in str){                // repeat process n times where n = str.length
    max=output=depth='';           // max: max depth, output: what to print, depth: current depth
    for(char of str)               // iterate over chars of str
      output+=
        line==(char<')'?depth++:--depth)? // update depth, if line is equal to current depth
        char:' ',                  // append either '(', ')', or ' '
        max=max<depth?depth:max;   // update max depth
    line<max&&console.log(output)  // print if current line is less than max depth
  }
}

대신에 1 바이트를 절약 n<m?console.log(o):0할 수 있습니다 n<m&&console.log(o).
Ismael Miguel

4

CJam, 43 41 36 바이트

너무 골프는 아니지만 (내 생각에는) 첫 번째 시도는 다음과 같습니다.

l:L,{)L<)_')=@~zS*\+}%_$0=,f{Se]}zN*

작동 원리

CJam에서 각각 증가 및 감소를 의미 한다는 매우 편리한 사실을 사용 )하고 (있습니다. 따라서 간단히 깊이를 얻기 위해 괄호를 평가합니다.

l:L,{)L<)_')=@~zS*\+}%_$0=,f{Se]}zN*
l:L,{                    }%                "Store input line in L and iterate over [0,L)";
     )L<                                   "substr(L, 0, iterator + 1)";
        )                                  "Slice off the last character to stack";
         _')=                              "Put 0 on stack if the sliced character is (,
                                            else 1 if sliced character is )";
             @~                            "bring forth the remaining
                                            brackets after slicing and evaluate them";
               zS*                         "Stack has negative depth number, take absolute
                                            value and get that many spaces";
                  \+                       "Prepend to the sliced character";
                      _$0=,                "Get the maximum depth of brackets";
                           f{Se]}          "Pad enough spaces after each string to match
                                            the length of each part";
                                 zN*       "Transpose and join with new lines";

여기에서 온라인으로 사용해보십시오


4

옥타브, 85 자

function r=p(s)i=j=0;for b=s k=b==40;k&&++j;t(j,++i)=9-k;k||--j;r=char(t+32);end;end

그것은 순진한 접근 방식의 최적화입니다. 실제로 Matlab과 Octave에서 매우 자연 스럽습니다.

function r=p(s)
i=j=1;
for b=s
 if b=='(' t(++j,i++)='(' else t(j--,i++)=')' end; end; t(~t)=' '; r=char(t);
end;

테이블 t 은 아직 존재하지 않을 수도 있으며, 어떤 요소에도 즉시 할당 할 수 있으며,이 요소가 존재하는 데 필요한 가장 작은 치수로 재구성되어 매우 편리합니다.


4

펄, 91 89 88 84 80 79 바이트

$t=<>;{$_=$t;s/\((?{$l++})|.(?{--$l})/$^R==$c?$&:$"/ge;print,++$c,redo if/\S/}
  • $ t는 입력 문자열입니다.
  • $ c는 현재 줄에 인쇄하려는 깊이입니다.
  • $ l은 우리가 en을 만난 후의 깊이입니다.
  • $ l은 정규식 임베디드 코드 블록 에서 업데이트됩니다 .
  • $ ^ R은 가장 최근 코드 블록의 결과입니다.

4

하스켈, 154 바이트

f h('(':s)=h:f(h+1)s;f h(')':s)=(h-1):f(h-1)s;f _ _=[]
main=interact$ \s->unlines[[if i==h then c else ' '|(c,i)<-zip s l]|let l=f 0 s,h<-[0..maximum l]]

다른 Haskell 솔루션과 동일한 아이디어이지만 다소 짧습니다. -사용법 :

echo  '(((())())(()))' | runghc Golf.hs

3

J, 46

다른 '골프 언어'만큼 크지는 않지만 내 방어에서 J는 문자열이 끔찍합니다.

[:|:(((,~(' '#~]))"0)(0,2%~[:+/\2+/\1-'(('i.]))~

문자열을 함수의 입력으로 사용합니다. J에서 더 좋은 방법이있을 것입니다.

용법:

   f=:[:|:(((,~(' '#~]))"0)(0,2%~[:+/\2+/\1-'(('i.]))~
   f '(()(()())()((())))(())'
(                )(  )
 ()(    )()(    )  () 
    ()()    (  )      
             ()       

J에서이 작업을 수행하는 또 다른 방법은 내 답변 을 참조하십시오.
FUZxxl

3
개인적으로 J는 문자열에 완벽하게 적합하다고 생각합니다. 배열 만 생각하면됩니다.
FUZxxl

3

루비 119 115 114

->s{r=[""]*s.size
d=0
s.chars.map{|l|r.map!{|s|s+" "}
b=l>"("?1:0
d-=b
r[d][-1]=l
d+=1-b}.max.times{|i|puts r[i]}}

설명:

->s{r=[""]*s.size  # Take an array of strings big enough
d=0                # This will contain the current depth
s.chars.map{|l|r.map!{|s|s+" "}  # Add a new space to every array
b=l>"("?1:0       # Inc/Dec value of the depth
d-=b               # Decrement depth if we are at a closing paren
r[d][-1]=l         # Set the corresponding space to the actual open/close paren
d+=1-b             # Increment the depth if we are at a opening paren
}.max.times{|i|puts r[i]}}  # Print only the lines up to the max depth

3

자바, 233214 바이트

void f(String s){int p,x,d,l=s.length();char c,m[]=new char[l*l];java.util.Arrays.fill(m,' ');p=x=0;while(x<l){d=(c=s.charAt(x))==40?p++:--p;m[d*l+x++]=c;}for(x=0;x<l*l;x++)System.out.print((x%l==0?"\n":"")+m[x]);}

들여 쓰기 :

void f(String s){
    int p, x, d, l = s.length();
    char c, m[] = new char[l * l];
    java.util.Arrays.fill(m, ' ');
    p = x = 0;
    while (x < l){
        d = (c = s.charAt(x)) == 40
                ? p++
                : --p;
        m[d * l + x++] = c;
    }
    for (x = 0; x < l * l; x++)
        System.out.print((x % l == 0 ? "\n" : "") + m[x]);
}

최종 루프가 단축 될 수는 있지만 독자에게 연습으로 남겨 두겠습니다. ;-)


오래된 233 바이트 답변 :

void f(String s){int y=s.length(),x=0;char[][]m=new char[y][y];for(char[]q:m)java.util.Arrays.fill(q,' ');y=0;for(char c:s.toCharArray())if(c=='(')m[y++][x++]=c;else m[--y][x++]=c;for(char[]q:m)System.out.println(String.valueOf(q));}

들여 쓰기 :

static void f(String s) {
    int y = s.length(), x = 0;
    char[][] m = new char[y][y];
    for(char[] q : m)
        java.util.Arrays.fill(q, ' ');
    y = 0;
    for(char c : s.toCharArray())
        if(c == '(')
            m[y++][x++] = c;
        else
            m[--y][x++] = c;
    for(char[] q : m)
        System.out.println(String.valueOf(q));
}

1 년 이상이 지났다는 것을 알고 있지만 "최종 루프가 단축 될 수있을 것 같지만 독자에게 연습으로 남겨 두겠습니다. ;-)"; 당신은 참으로 맞습니다. 그것은 변경 될 수 for(x=0;x<l*l;x++)System.out.print((x%l==0?"\n":"")+m[x]);for(x=0;x<l*l;)System.out.print((x%l==0?"\n":"")+m[x++]);-1 바이트 대한. 또한 필드를 초기화 할 때 제거 p=x=0하고 사용 하여 2 바이트를 더 절약 할 수 있습니다 int p=0,x=0,. 전체적으로 211 바이트됩니다 .
Kevin Cruijssen

3

C #, 195 바이트

먼저 골프를 해보세요-내가 잘못한 경우 소리 지르십시오.

SetCursorPosition을 사용하고 입력을 명령 줄 인수로 사용하여 왼쪽에서 오른쪽으로 작업하는 대체 C # 버전.

using System;class P{static void Main(string[] a){Action<int,int>p=Console.SetCursorPosition;int r=0,c=0;foreach(var x in a[0]){r+=x==')'?-1:0;p(c,r);Console.Write(x);r+=x=='('?1:0;p(c,r);c++;}}}

필자는 전체 라인이 아닌 열기 / 닫기 패런을 기반으로 쓰기 위치를 조정하는 것이 재미있을 것이라고 생각했습니다. Paren 닫기는 쓰기 전에 위치를 위로 이동합니다. 열린 en은 글을 쓴 후 아래로 이동합니다. ActionSetCursorPosition은 5 바이트를 절약합니다. 출력 후 커서를 다음 줄로 이동하면 약간의 시간이 더 걸립니다.

using System;
class P
{
    static void Main(string[] a)
    {
        Action<int, int> p = Console.SetCursorPosition;
        int r = 0, c = 0;
        foreach (var x in a[0])
        {            
            r += x == ')' ? -1 : 0;
            p(c, r);
            Console.Write(x);
            r += x == '(' ? 1 : 0;
            p(c, r);
            c++;
        }
    }
}

3

배치, 356335 바이트

나는이 도전에 대한 배치 솔루션이 이미 있다는 것을 알고 있지만, 이것은 훨씬 더 골프를 치고 다른 접근법을 취하는 것 같습니다. 가장 중요한 것은 다른 배치 솔루션에는 하나 이상의 powershell 명령이 포함되어 있습니다. 이 솔루션은 그렇지 않습니다.

@echo off
setlocal enabledelayedexpansion
set p=%1
set p=%p:(="(",%
set p=%p:)=")",%
set c=0
for %%a in (%p%)do (if ")"==%%a set/ac-=1
set d=!d!,!c!%%~a
if "("==%%a set/ac+=1&if !c! GTR !m! set m=!c!)
set/am-=1
for /l %%a in (0,1,!m!)do (for %%b in (!d!)do (set t=%%b
if "%%a"=="!t:~0,-1!" (cd|set/p=!t:~-1!)else (cd|set/p=. ))
echo.)

U+0008점 다음의 마지막 줄 에는 백 스페이스 문자 ( )가 있습니다 (12 행, 57 열). 여기에 게시 된 코드에는 표시되지 않지만 바이트 수에는 포함됩니다.


다른 사람이 실제로 Batch-Nice one +1로 답변을 제출합니다.
unclemeat

3

배치, 424 바이트

@echo off
setLocal enableDelayedExpansion
set s=%1
set a=1
:c
if defined s (set/ac+=1
set "z="
if "%s:~0,1%"=="(" (set "1=(")else (set/aa-=1
set "1=)")
for %%a in (!a!)do for /f usebackq %%b in (`powershell "'!l%%a!'".Length`)do (set/ay=!c!-%%b
for /l %%a in (1,1,!y!)do set z= !z!
set "l%%a=!l%%a!!z!!1!")
if "%s:~0,1%"=="(" set/aa+=1
if !a! GTR !l! set/al=!a!-1
set "s=%s:~1%"
goto c)
for /l %%a in (1,1,!l!)do echo !l%%a!

언 골프 :

@echo off
setLocal enableDelayedExpansion

set s=%1
set a=1
set c=0
set l=0

:c
if defined s (
    set /a c+=1
    set "z="
    if "%s:~0,1%"=="(" (
        set "1=("
    ) else (
        set /a a-=1
        set "1=)"
    )
    for %%a in (!a!) do for /f usebackq %%b in (`powershell "'!l%%a!'".Length`) do (
        set /a y=!c!-%%b
        for /l %%a in (1,1,!y!) do set z= !z!
        set "l%%a=!l%%a!!z!!1!"
    )
    if "%s:~0,1%"=="(" set /a a+=1
    if !a! GTR !l! set /a l=!a!-1
    set "s=%s:~1%"
    goto c
)

for /l %%a in (1,1,!l!) do echo !l%%a!

예:

h:\>par.bat (((())())(()))
 (            )
  (      )(  )
   (  )()  ()
    ()

3

C, 118 117 바이트

C의 또 다른 대답이지만 내 것이 더 짧습니다.

c;d;main(m,v)int**v;{while(d++<m){char*p=v[1];while(*p)c+=*p==40,putchar(c-d?*p:32),m=c>m?c:m,c-=*p++==41;puts("");}}

언 골프 버전 :

c; /* current depth */
d; /* depth to print in current row */
main(m,v)int**v;{
    while(d++<m) {
        char*p=v[1];
        while(*p){
            c+=*p==40;           /* 40 = '(' */
            putchar(c-d?*p:32); /* 32 = ' ' (space) */
            m=c>m?c:m;           /* search maximum depth */
            c-=*p++==41;         /* 41 = ')' */
        }
        puts("");
    }
}

그리고 작동합니다!

% ./telescope '()(())((()))(())()'
()(  )(    )(  )()
   ()  (  )  ()
        ()
% ./telescope '((()())()(()(())()))'
(                  )
 (    )()(        )
  ()()    ()(  )()
             ()

1
그러나 매우 우아한 솔루션 putchar(c-d?32:*p)은 한 문자보다 짧습니다 putchar(c==d?*p:32).
pawel.boczarski

2

하스켈, 227 바이트

n _ []=[]
n h ('(':r)=('(',h):n(h+1)r
n d (')':r)=let h=d-1 in(')',h):n h r
m n []=n
m n ((_,h):r)=m(max h n)r
p s=let v=n 0 s;h=m 0 v;in map(\d->map(\(b,l)->if l==d then b else ' ')v)[0..h]
main=fmap p getLine>>=mapM_ putStrLn

1
연산자를 사용하여 몇 개의 공백을 절약 할 수 있습니다 (예 : n#[]대신) m n [].
Franky

2

펄, 76 바이트

$a[/\(/?$l++:--$l][$i++]=$_ for split//,<>;print map{$_||' '}@$_,"\n"for@a

아니오 use strict:)


2

렉스, 94 바이트

Linux 콘솔 코드에 따라 다릅니다. gcc를 사용하면 두 인스턴스를 모두 \33실제 이스케이프 문자 로 바꾸어 4 바이트를 잘라낼 수 있습니다 .

%%
 int p[2]={0};
\( printf("(\33D");++p[!*p];
\) printf("\33M)");--*p;
\n while(p[1]--)ECHO;

컴파일하고 실행하려면 :

$ flex -o telescopic.c telescopic.l
$ gcc -o telecopic telescopic.c -lfl
$ ./telescopic
(()(()())()((())))(())
(                )(  )
 ()(    )()(    )  ()
    ()()    (  )
             ()
--- type ctrl-D ---
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.