วงเล็บแบบยืดได้


79

พิจารณาสตริงที่ไม่ว่างเปล่าของวงเล็บที่สมดุลอย่างถูกต้อง:

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

เราสามารถจินตนาการได้ว่าวงเล็บแต่ละคู่แสดงถึงวงแหวนในโครงสร้างแบบยืดหดได้ ลองขยายกล้องโทรทรรศน์ออก:

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

อีกวิธีในการดูคือวงเล็บที่ความลึกnถูกย้ายไปที่บรรทัดnในขณะที่รักษาตำแหน่งแนวนอนไว้

งานของคุณคือการใช้สตริงของวงเล็บที่มีความสมดุลและสร้างเวอร์ชันเพิ่มเติม

คุณสามารถเขียนโปรแกรมหรือฟังก์ชั่น, รับอินพุตผ่าน STDIN (หรือเทียบเท่าที่ใกล้เคียงที่สุด), อาร์กิวเมนต์บรรทัดคำสั่งหรือพารามิเตอร์ฟังก์ชัน, และสร้างเอาต์พุตผ่าน STDOUT (หรือเทียบเท่าที่ใกล้เคียงที่สุด), ค่าส่งคืนหรือฟังก์ชัน (ออก)

คุณอาจสมมติว่าสายป้อนข้อมูลที่ถูกต้องคือประกอบด้วยวงเล็บเท่านั้นซึ่งมีความสมดุลอย่างถูกต้อง

คุณอาจพิมพ์ช่องว่างต่อท้ายในแต่ละบรรทัด แต่ไม่ต้องเว้นวรรคนำหน้าเกินความจำเป็น ยอดรวมบรรทัดต้องไม่ยาวเกินกว่าสองเท่าของความยาวของสตริงป้อนเข้า คุณสามารถเลือกที่จะพิมพ์ขึ้นบรรทัดใหม่ได้

ตัวอย่าง

นอกเหนือจากตัวอย่างข้างต้นต่อไปนี้เป็นกรณีทดสอบอีกสองสามรายการ (อินพุตและเอาต์พุตถูกคั่นด้วยบรรทัดว่าง)

()

()
(((())))

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

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

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

ความท้าทายที่เกี่ยวข้อง:

  • Topographic Stringsซึ่งขอให้คุณสร้างสิ่งที่เป็นส่วนประกอบของผลลัพธ์ในการท้าทายนี้
  • โค้ดคำอธิบายฟอร์แมตเตอร์ความกว้างทั่วไปของแนวคิดในการท้าทายนี้โพสต์เมื่อเร็ว ๆ นี้โดย PhiNotPi (อันที่จริงคำอธิบายดั้งเดิมของ PhiNotPi เกี่ยวกับความคิดของเขาคือสิ่งที่เป็นแรงบันดาลใจให้กับความท้าทายนี้)

ลีดเดอร์

อืมมีส่วนร่วมค่อนข้างมากดังนั้นนี่คือ Stack Snippet เพื่อสร้างทั้งกระดานผู้นำปกติและภาพรวมของผู้ชนะตามภาษา

เพื่อให้แน่ใจว่าคำตอบของคุณปรากฏขึ้นโปรดเริ่มคำตอบด้วยหัวข้อโดยใช้เทมเพลต Markdown ต่อไปนี้:

# Language Name, N bytes

ที่Nมีขนาดของส่งของคุณ หากคุณปรับปรุงคะแนนของคุณคุณสามารถเก็บคะแนนเก่าไว้ในบรรทัดแรกโดยการตีพวกเขาผ่าน ตัวอย่างเช่น

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


17
หัวข้อสำรอง: De-Lisp-ify a string : P
Alex A.

1
มีข้อ จำกัด เกี่ยวกับสีของเอาต์พุตหรือไม่?
Matteo Italia

1
@ MartinBüttner: ไม่เป็นไรฉันพบวิธีที่สะอาดกว่า สมมติว่าความคิดก่อนหน้าของฉันจะโกนไบต์ให้เหลือวงเล็บปิดที่กระพริบสีน้ำเงินมากกว่าสีฟ้า ... :-)
Matteo Italia

8
@ MatteoItalia โอ้พระเจ้าฉันดีใจที่ไม่ได้เกิดขึ้น ;)
Martin Ender

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=

ด้านบนเป็นดัมพ์ xxd ที่สามารถย้อนกลับได้เนื่องจากซอร์สโค้ดมีอักขระที่ไม่สามารถพิมพ์ได้ VT (0x0b) และ CSI (0x9b)

ชอบคำตอบนี้จะใช้ลำดับหนี 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

x86 ชุดสำหรับ DOS ด้วยเทคนิค:

    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ก่อนที่จะใช้เป็นข้อบังคับเกือบ;
  • สีน่าเกลียด นั่นเป็นผลมาจากการรีไซเคิลอักขระถัดไปเป็นคุณลักษณะสีเพื่อประหยัดสองไบต์ที่นี่และที่นั่น
  • รหัสจะถือว่าbh=0และธงทิศทางชัดเจนเมื่อเริ่มต้นทั้งที่ไม่มีเอกสาร OTOH ได้bxรับการตั้งค่าเป็นศูนย์อย่างชัดเจนในทุกรูปแบบของ DOS ที่ฉันเห็น (DosBox, MS-DOS 2, FreeDOS) และทุกที่ที่ฉันทดสอบธงนั้นก็โอเคแล้ว

ป้อนคำอธิบายรูปภาพที่นี่


เพิ่งยืนยันสิ่งนี้ ใช่มันใช้งานได้ คุณแน่ใจหรือว่าต้องทำcld?
FUZxxl

@FZZxxl: บน DosBox มันใช้งานได้ดีแม้ว่าจะไม่มีมัน แต่ก็ดูที่แหล่งที่มามันบอกว่าธงถูกเก็บรักษาไว้จากสิ่งที่เกิดขึ้นใน DOS และใน TRSs ก่อนดังนั้นอาจจะต้องเล่นอย่างปลอดภัย ทั้งนี้ที่จะเป็นเพียงหนึ่งไบต์ผลตอบแทนที่แท้จริงจะฆ่าอย่างน้อยหนึ่งในบรรดาใหญ่ (= 4 ไบต์ในแต่ละ) /add sub
Matteo Italia

หืม ... ไม่มีความคิดจริง ๆ
FUZxxl

คุณเปลี่ยนlopเป็นloopเหรอ
mbomb007

@ mbomb007: อาจจะ? ฉันไม่แน่ใจว่าnasmdisambiguates ระหว่างloopเป็นฉลากและloopคำแนะนำการชุมนุมดังนั้นฉันแค่เขียนlopเหมือนคนอื่น ๆ
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

วิธีนี้ทำให้ฉันปวดหัว:')
Nic Hartley

@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
สิ่งที่ Retina คืออะไร?
FUZxxl

2
@FZZxxl เป็นภาษาการเขียนโปรแกรมตาม regex ของฉันเอง ดู GitHub
Martin Ender

2
ทำไม\eบวกprintf? คุณสามารถใส่อักขระควบคุมในรูปแบบการแทนที่
Dennis

15

TI-BASIC, 69 60 56 55 ไบต์

สิ่งนี้มีไว้สำหรับเครื่องคิดเลขตระกูล TI-83 + / 84 + ถึงแม้ว่ามันจะถูกเขียนใน 84+ C Silver Edition

โปรแกรมแสดงให้เห็นว่ามีขนาดใหญ่ขึ้นเมื่อคำนวณเนื่องจากมีการรวมข้อมูล VAT + ขนาด นอกจากนี้ยังมีอักขระมากกว่า 56 ตัวที่นี่; เหตุผลที่มันเป็น 56 ไบต์เนื่องจากคำสั่งทั้งหมดที่มีอักขระมากกว่าหนึ่งตัวถูกบีบอัดจนถึงโทเค็นที่มีขนาดหนึ่งหรือสองไบต์

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
Ahhh ภาษาโปรแกรมแรกของฉัน ขอบคุณสำหรับความคิดถึงฮ่าฮ่า
Alex Pritchard

1
ยังคงวางโปรแกรม TI สำหรับคลาสคณิตศาสตร์ระดับมัธยมซึ่งมีประโยชน์มากที่จะมีสูตรในตัวที่จะคำนวณให้คุณในการทดสอบและการมอบหมาย
Elias Benevedes

1
หากคุณเปลี่ยนสิ่งต่าง ๆ รอบ ๆ คุณสามารถใช้cos(piAnsเคล็ดลับเพื่อบันทึกไบต์อื่น
lirtosiast

9

Python 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)

การเรียกเช่นf("((()())()(()(())()))")นั้นและเอาท์พุทคือ STDOUT

การอธิบาย

n = 0เราเริ่มต้นด้วย สำหรับอักขระแต่ละตัวในบรรทัดอินพุต:

  • ถ้า char เป็น(เราnจะเพิ่มช่องว่างที่เพิ่มขึ้นn
  • ถ้า char เป็น)เราจะลดลงnแล้วเติมnช่องว่าง

ผลลัพธ์จะถูกซิปแล้วและพิมพ์ออกมา โปรดทราบว่าzipรหัสไปรษณีย์ของ Python ให้ตรงกับความยาวขององค์ประกอบที่สั้นที่สุดเช่น

>>> 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)]

Python 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)

ไม่มีซิปเพียง padding ljustเหมาะสมกับ อันนี้ดูเหมือนจะมีศักยภาพในการเล่นกอล์ฟ


8

R, 151 127 ตัวอักษร

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

มันอ่านสตริงเป็น stdin โดยแยกเป็นเวกเตอร์ของอักขระเดี่ยวคำนวณผลรวมสะสมของ(และ)แทนที่ส่วนก่อนกับหลัง (ด้วยความล่าช้า) ดังนั้นจึงคำนวณ "ระดับ" ของวงเล็บแต่ละอัน จากนั้นจะพิมพ์ไปยัง 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ไม่จำเป็นจริงๆ แต่คุณจะต้องเปลี่ยนส่วนซัมเมอร์เล็กน้อย D=c(C(S=="("),0)-c(0,C(S==")"));นำมาไว้ที่ 135
MickyT

@MickyT ว้าวขอบคุณมาก! ไม่ได้คิดอย่างนั้น whichไม่จำเป็นจริงๆที่นี่ ( D!=jเป็นเวกเตอร์ของ booleans แล้วอนุญาตให้ทำดัชนี) ผมไม่ทราบว่าอาร์กิวเมนต์fillสำหรับcatที่เป็นเคล็ดลับที่ดี! ขอบคุณที่ทำให้ฉันสั้นลงด้วยตัวละครที่น่าทึ่ง 24 ตัว !!
plannapus

8

C, 58 53 52 51 49 ไบต์

ทำให้การใช้ ANSI escape sequences เพื่อย้ายตำแหน่งเคอร์เซอร์

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

หากไม่ได้ใช้ gcc หรือคอมไพเลอร์อื่นที่รองรับ\eจะสามารถแทนที่ด้วย\x1Bรวมเป็นพิเศษ 2 ไบต์ \e[Aเลื่อนเคอร์เซอร์ขึ้นหนึ่งแถวและ\e[Bเลื่อนเคอร์เซอร์ลงหนึ่งแถว ก็ไม่จำเป็นที่จะใช้\e[Bในการย้ายลงหนึ่งแถวเป็นมันทั้งสองไบต์สั้นเพื่อใช้อักขระ ASCII แท็บแนวตั้งหรือ0xB\v

สายป้อนสันนิษฐานจากคำถามที่ประกอบด้วยเท่านั้น (สมดุล) วงเล็บดังนั้นการตรวจสอบความเท่าเทียมกันของตัวละครที่มี&1ก็เพียงพอที่จะแยกแยะระหว่างและ()


7

Pip, 53 ไบต์

Pipเป็นภาษารหัสกอล์ฟของการประดิษฐ์ของฉัน รุ่นแรกได้รับการตีพิมพ์ในวันเสาร์ดังนั้นฉันจึงสามารถรับรางวัลได้อย่างเป็นทางการ! วิธีการแก้ปัญหาด้านล่างนี้ไม่สามารถแข่งขันได้อย่างรุนแรงเมื่อภาษากอล์ฟเล่นไป แต่ส่วนหนึ่งเป็นเพราะฉันยังไม่ได้ใช้งานเช่น zip และ max

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

คาดหวังว่าสตริงของวงเล็บเป็นอาร์กิวเมนต์บรรทัดคำสั่ง

รุ่น "Ungolfed":

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-gใน Pip เป็นตัวแปรของฟังก์ชันในเครื่อง แต่h-zเป็นโกลบอลvมีประโยชน์เพราะมันถูกกำหนดค่าเป็น -1)

ต่อไปเราใช้While loop เพื่อสร้างและพิมพ์แต่ละบรรทัดจนกว่าบรรทัดที่สร้างจะประกอบด้วยช่องว่างทั้งหมด vตอนนี้ใช้สำหรับคอลัมน์และiแถว {z@++v=i?as}ฟังก์ชั่นแมปซ้ำ ๆ เพื่อสายป้อนต้นฉบับการทดสอบว่าบรรทัดปัจจุบันiตรงกับสายวงเล็บปัจจุบันควรจะเป็นบน (ตามที่เก็บไว้ในzรายการ) ถ้าเป็นเช่นนั้นใช้วงเล็บ ( a); ถ้าไม่ใช้ให้ใช้s(กำหนดค่าเริ่มต้นให้กับพื้นที่) ผลลัพธ์ที่ได้คือในแต่ละการวนซ้ำoได้รับการกำหนดรายการของตัวละครเทียบเท่ากับบรรทัดถัดไปของการส่งออก

เพื่อทดสอบว่าเราควรวนรอบต่อไปหรือไม่เราตรวจสอบว่าoช่องว่างทั้งหมดว่างRMเปล่าหรือไม่ ถ้าไม่ใช่ให้พิมพ์ (ซึ่งโดยค่าเริ่มต้นเชื่อมทุกอย่างเข้าด้วยกันเช่นเดียวกับใน 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ทำส่วนใหญ่ของการยกของหนัก แต่ต้องทำงานกับวงเล็บปีกกาแทน parens ส่วนที่เหลือเป็นการปรับเปลี่ยนของคำตอบนี้indentจะย้ายการส่งออกของ


5

Python 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(ที่จริงแล้วคือการปฏิเสธ) ไปยังสตริงอินพุตsและสร้างสตริงใหม่zที่มีอักขระsที่ระดับความลึกiเท่านั้น สิ่งนี้ทำได้โดยการเพิ่มหรือลดiเพื่อติดตามความลึกปัจจุบันและการเพิ่มตัวละครปัจจุบันเมื่อiมีการ0ปรับสำหรับประเภท Paren และเพิ่มช่องว่าง

จากนั้นพิมพ์และเรียกซ้ำไปiยังบรรทัดถัดไปยกเว้นว่าบรรทัดปัจจุบันคือช่องว่างทั้งหมด โปรดทราบว่าเนื่องจาก parens มีความสมดุลวงiหลังจะเหมือนกับเมื่อเริ่มต้น

งูหลาม 3 print(z)จะเหมือนกันยกเว้นสำหรับตัวอักษรสำหรับ


5

การโกง :( Retina + TeX, N ไบต์การโกง :(

ใช้งานได้เฉพาะถ้าคุณแสดงผล (?) เอาต์พุตโดยใช้ MathJax หรือ TeX อื่น ๆ ซึ่งปัจจุบันปิดใช้งานสำหรับ SE นี้ :(

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

แต่ละบรรทัดควรอยู่ในไฟล์ที่แตกต่างกัน แต่คุณสามารถทดสอบได้โดยใช้Retina -e "\(" -e "({" -e "\)" -e "})" -e "\{\(" -e "_{("(หรือคำสั่ง sed เทียบเท่าsed -e "s/(/({/g;s/)/})/g;s/{(/_{(/g") อินพุตถูกส่งผ่าน STDIN

มันทำงานได้โดยการใส่เนื้อหาของวงเล็บแต่ละคู่ไว้ในวงเล็บและจากนั้นห้อยสิ่งของทั้งหมดที่อยู่ภายใน

เอาท์พุต

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

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

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

เอาต์พุต TeX


1
ฉันภูมิใจที่คุณใช้ Retina และนี่เป็นความคิดที่ดีนอกกรอบ แต่นั่นไม่ใช่สิ่งที่ผลลัพธ์ควรจะเป็น ;) โดยเฉพาะอย่างยิ่งนี่เป็นการละเมิดสูตรทางเลือก "อีกวิธีหนึ่งในการดูมันคือวงเล็บที่ความลึก n ถูกย้ายไปที่บรรทัด n ในขณะที่รักษาตำแหน่งแนวนอนไว้" ฉันประทับใจมากกับโซลูชัน Retina ที่บริสุทธิ์และเป็นไปตามกฎและอาจมอบรางวัลให้กับมัน ;)
Martin Ender

In total the lines must not be longer than twice the length of the input string. การเปลี่ยนบรรทัดที่ 2 เป็น(\,{และบรรทัดที่ 4 เพื่อ}\,)หมายความว่าเอาต์พุตเหมาะสมกับสิ่งนี้ (แม้ว่าความลึกแนวตั้งยังไม่ถูกต้อง: ()
22723

ฉันจัดการเพื่อสร้างโซลูชันที่สอดคล้องกับกฎ
:)

1
งานที่ดี. ฉันเดาว่านั่นหมายความว่าคุณสามารถลบคำตอบที่โกงได้ตอนนี้ ;)
Martin Ender

5

Java, 232 226 224 222 bytes

รุ่น Golfed:

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

Javascript / 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
  }
}

แทนที่จะn<m?console.log(o):0ใช้คุณสามารถใช้n<m&&console.log(o)ซึ่งบันทึก 1 ไบต์
Ismael Miguel

4

CJam, 43 41 36 bytes

ไม่เล่นกอล์ฟมากเกินไป (ฉันคิดว่า) แต่นี่เป็นความพยายามครั้งแรกของฉัน:

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

Perl, 91 89 88 84 80 79 ไบต์

$t=<>;{$_=$t;s/\((?{$l++})|.(?{--$l})/$^R==$c?$&:$"/ge;print,++$c,redo if/\S/}
  • $ t คือสตริงอินพุต
  • $ c คือความลึกที่เราต้องการพิมพ์ในบรรทัดปัจจุบัน
  • $ l คือความลึกที่เราอยู่หลังจากเผชิญหน้ากับ paren
  • $ ลิตรมีการปรับปรุงในregex ฝังบล็อกรหัส
  • $ ^ R เป็นผลลัพธ์ของการบล็อกโค้ดล่าสุด

4

Haskell, 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

Java, 233 214 ไบต์

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));
}

ฉันรู้ว่ามันใช้เวลานานกว่าหนึ่งปี แต่ "ฉันเดาว่าลูปสุดท้ายอาจสั้นลง แต่ฉันจะปล่อยให้มันเป็นแบบฝึกหัดให้กับผู้อ่าน ;-)"; คุณพูดถูก มันสามารถเปลี่ยนจาก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 ไบต์ นอกจากนี้คุณยังสามารถบันทึกได้อีก 2 ไบต์โดยการลบp=x=0และใช้เพียงการint p=0,x=0,เริ่มต้นของฟิลด์แทน ทั้งหมดมันจะกลายเป็น211 ไบต์
Kevin Cruijssen

3

C #, 195 ไบต์

ลองเล่นกอล์ฟก่อนถ้าฉันทำอะไรผิด

เวอร์ชัน C # ทางเลือกโดยใช้ SetCursorPosition และทำงานจากซ้ายไปขวาโดยรับอินพุตเป็น commandline ARG

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++;}}}

ฉันคิดว่ามันคงจะสนุกถ้าได้ปรับตำแหน่งการเขียนโดยอิงจาก open / close paren และไม่ใช่ full lines ใกล้ชิดเลื่อนตำแหน่งขึ้นก่อนที่จะเขียน; paren แบบเปิดเลื่อนลงหลังจากเขียน การดำเนินการ SetCursorPosition บันทึกห้าไบต์ การย้ายเคอร์เซอร์ไปที่บรรทัดถัดไปหลังจากเอาต์พุตจะใช้เวลาเพิ่มขึ้นเล็กน้อย

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

แบตช์356 335 ไบต์

ฉันรู้ว่ามีวิธีแก้ปัญหาแบบแบทช์สำหรับความท้าทายนี้อยู่แล้ว แต่อันนี้มีการตีกอล์ฟมากขึ้นอย่างมากและดูเหมือนจะใช้แนวทางที่แตกต่าง ที่สำคัญที่สุดโซลูชันแบตช์อื่น ๆ มีคำสั่ง 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
ลุง

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 Bytes

คำตอบอื่นใน 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

Haskell, 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

เล็ก, 94 ไบต์

ขึ้นอยู่กับรหัสคอนโซล Linux ด้วย gcc คุณสามารถตัดสี่ไบต์โดยแทนที่ทั้งสองอินสแตนซ์\33ด้วยอักขระ escape จริง

%%
 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.