Teleskopik Parantezler


79

Boş olmayan, doğru dengelenmiş bir parantez dizisi düşünün:

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

Her parantez çiftinin daraltılmış bir teleskopik yapıdaki bir halkayı temsil ettiğini hayal edebiliyoruz . Öyleyse teleskopu uzatalım:

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

Buna bakmanın başka bir yolu da n derinliğindeki parantezlerin yatay pozisyonlarını koruyarak n çizgisine hareket etmeleridir.

Senin görevin böyle bir parantez parantez almak ve genişletilmiş sürümünü üretmektir.

STDIN (veya en yakın eşdeğeri), komut satırı argümanı veya işlev parametresi üzerinden giriş alarak ve STDOUT (veya en yakın eşdeğeri), return değeri veya function (out) parametresi üzerinden çıktı üreten bir program veya işlev yazabilirsiniz.

Giriş dizesinin geçerli olduğunu, yani yalnızca doğru şekilde dengelenmiş parantezleri içerdiğini varsayabilirsiniz.

Her satırda sondaki boşlukları yazdırabilirsiniz, ancak gerekenden daha fazla sayıda ön boşluk bırakamazsınız. Toplamda, satırların giriş dizesinin uzunluğunun iki katından daha uzun olmaması gerekir. İsteğe bağlı olarak tek bir izleyen yeni satır yazdırabilirsiniz.

Örnekler

Yukarıdaki örneğe ek olarak, birkaç test durumu daha var (giriş ve çıkış boş bir satırla ayrılmıştır).

()

()
(((())))

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

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

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

İlgili Zorluklar:

  • Topografik Dizgiler , bu zorluktaki çıktının tamamlayıcısı olan şeyi üretmenizi ister.
  • Kod Açıklaması Formatter , bu zorluktaki fikirlerin geniş bir genellemesi, son zamanlarda PhiNotPi tarafından yayınlandı. (Aslında, PhiNotPi'nin fikrinin orijinal açıklaması bu zorluğa ilham veren şeydi.)

Liderler

Huh, bu oldukça fazla katılım sağladı, bu yüzden işte hem düzenli bir lider tablosu hem de kazananların dile göre genel bir bakışı oluşturmak için bir Stack Snippet.

Cevabınızın göründüğünden emin olmak için, lütfen aşağıdaki Markdown şablonunu kullanarak cevabınızı bir başlık ile başlatın:

# Language Name, N bytes

nerede NGönderinizden boyutudur. Puanınızı artırmak varsa, olabilir onları içinden vurarak, başlığa eski hesapları tutmak. Örneğin:

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


17
Alternatif başlık: Dize-Lisp-ify bir dize. : P
Alex A.

1
Çıktının rengiyle ilgili herhangi bir kısıtlama var mı?
Matteo Italia

1
@ MartinBüttner: nevermind, daha temiz bir yol buldum; Diyelim ki önceki fikrim, tüm kapalı parantezleri mavi üzerine mavi renkte yanıp sönen bırakarak bir baytı traş edecekti ... :-)
Matteo Italia

8
@MatteoItalia oh tanrım, olmadığına sevindim. ;)
Martin Ender

12
@MatteoItalia: Bu sürümü yayınla! Görülmeye değer.
user2357112

Yanıtlar:


8

CJam, 17 16 15 bayt

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

Kaynak kodu yazdırılamayan VT (0x0b) ve CSI (0x9b) karakterlerini içerdiğinden, yukarıdaki geri dönüşümlü bir xxd dökümüdür.

Bu cevap gibi ANSI çıkış dizilerini kullanır , ancak dikey sekmeleri de kullanır ve printf kullanmaktan kaçınmak için kontrol karakterlerini doğrudan yazdırır .

Bu, çoğu Windows olmayan terminal emülatörünü içeren, destekleyici bir video metin terminali gerektirir.

Test sürüşü

LANG kabuk değişkenini ve terminal emülatörünün ISO 8859-1 kodlamasını ayarlamalıyız. İlki yürüterek elde edilir

$ LANGsave="$LANG"
$ LANG=en_US

Ayrıca, gerçek kodu çalıştırmadan önce, istemi devre dışı bırakır ve ekranı temizleriz.

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

Bu, çıkışın doğru şekilde gösterilmesini sağlar.

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

LANG'ı ve istemini geri yüklemek için şunu yürütün:

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

Nasıl çalışır

Her sonra dikey bir sekme eklemek ( aşağı imleç ve byte dizisini taşımak 9b 41 ( "\x9bA"her birinden önce) ) imleç yukarı hareket ettirmek için.

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 makine kodu, 39 34 33 30 29 bayt

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

Bazı hilelerle, DOS için x86 derlemesi:

    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

Sınırlamalar :

  • ilk önce silmeden, daima ekranın altından başlayarak basar; a clskoşmadan önce neredeyse zorunludur;
  • renkler çirkin; bu, bir sonraki karakteri, burada ve oradaki iki baytı kurtarmak için renk özellikleri olarak geri dönüştürmenin sonucudur;
  • kod varsayılır bh=0ve her ikisi de belgesiz olarak başlangıçtaki bayrak işareti silinir; OTOH, bxaçıkça gördüğüm tüm DOS değişkenlerinde sıfıra ayarlanmış (DosBox, MS-DOS 2, FreeDOS) ve test ettiğim her yerde bayrakları zaten iyi.

görüntü tanımını buraya girin


Sadece bunu doğruladım. Evet çalışıyor. Yapman gerektiğine emin misin cld?
FUZxxl

@ FUZxxl: DosBox'ta onsuz bile iyi çalışıyor, ancak kaynaklarına baktığımızda bayrakların DOS'ta ve TRS'lerde olanlardan korunduğunu söylüyor, bu yüzden muhtemelen güvenli bir şekilde oynaması gerekiyor. Her neyse, bu sadece bir bayt olurdu gerçek ödeme o büyük (= 4 bayt her) en az biri öldürmek olurdu add/ ' sub.
Matteo Italia

Hm ... hiçbir fikrim yok, gerçekten.
FUZxxl

Eğer değiştirebilir miyim lopiçin loop?
mbomb007 22.03.2015

@ mbomb007: belki? Bir etiket ile montaj talimatı nasmarasında ayırımcı olup olmadığından emin değilim , bu yüzden diğer herkes gibi yazarım . looplooplop
Matteo Italia

28

J, 32 28 bayt

Bu eğlenceli bir şeydi.

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

açıklama

Bu, nasıl golf oynadığının bir açıklaması da dahil olmak üzere, bu şekilde işler.

   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
Çok hoş! Çözüm harika parçalarla dolu!
randomra

1
(Genellikle, örneğin, deneyimli olmayan kullanıcıların da deneyebileceği bir işlev çağrısı eklerim.)
randomra

Bu çözüm başımı ağrıtıyor:')
Nic Hartley

@QPaysTaxes Bunu bir iltifat olarak kabul ediyorum.
FUZxxl

@ FUZxxl Öyle. Aynı zamanda cevabınızda beliren bir dizi karaktere dayanan bir kelime oyunu.
Nic Hartley

15

C, 150 bayt

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

Bu oldu çılgın golf eğlenceli. Hala işim bittiğine ikna olmadım.

fDizeyi girdi olarak alan ve stdout'a çıktı veren tek bir işlev tanımladık .

Hadi koddan geçelim, satır satır:

/* 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!
}

Her türlü sorunuza cevap vereceğim!

Online bir test programı deneyin !


"Char l = strlen (c) +1, o [l * l]" nin geçerli olmadığını hatırlamak istiyorum çünkü bunun gibi değişken büyüklükte bir dizi tanımlayamıyorsunuz, ancak hiçbir şey denememden bu yana 15 yıl geçti. C. bu sıralama
Sparr

@ Sparr Derleyicim bir uyarı bile atmıyor. Bunun C99'da "resmi olarak" standart olduğuna inanıyorum. Bunun için bir referans bulmaya çalışacağım.
BrainSteel

1
@Sparr İşte bir referans.
BrainSteel

Teşekkürler. Bu konuda 15 yıl önce (birkaç tane vermek veya almak) bu konuda işler değişmiş gibi görünüyor :)
Sparr

1
It @CoolGuy ancak sonraki çağrılarda olur f, mbu yasadışı "ortamınızı kırma" olarak sayılır 0'a reset olmaz burada .
BrainSteel

15

Retina + Bash, 27 bayt (14 + 10 + 3 = 27)

Bu ANSI Kaçışlarını kullanır:

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

Eşdeğer sed -e "s/(/(\\\e[B/g;s/)/\\\e[A)/g". Çıkış \e[Bkodu imleci bir satır aşağı hareket ettirmek ve \e[Aaraçlar imleci bir satır yukarı hareket ettirmek anlamına gelir, bu nedenle bu çözüm basit bir şekilde her bir yuvalanmış parantez çiftinin başlangıcından ve sonundan önce bu kodları ekler. Giriş STDIN'den geçirilir.

printf $(Retina ...)Çıktıyı doğru görebilmek için onu aramanız gerekecektir .

Çıktı

(((())))
(\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
Fena değil! İhtiyacı olmayan belirli bir terminale işaret edebilirseniz ,printf bu harika olurdu. Aksi takdirde, yalnızca | printfbayt sayısını eklemek için adil olacağını düşünüyorum .
Martin Ender

@ MartinBüttner Olmalı printf $()ya da olmalı printf $(Retina ).
jimmy23013

1
Retina meselesi nedir?
FUZxxl

2
@ FUZxxl Kendi regex tabanlı programlama dilim. GitHub'a bakın .
Martin Ender

2
Neden \eartı printf? Kontrol karakterlerini değiştirme modeline yerleştirebilirsiniz.
Dennis,

15

TI-BASIC, 69 60 56 55 bayt

Bu, 84+ C Silver Edition'da yazılmış olmasına rağmen, TI-83 + / 84 + hesap makinesi ailesi içindir.

KDV + boyut bilgisi dahil olduğundan program daha büyük hesapla gösterilir. Ayrıca, burada 56'dan fazla karakter var; 56 baytın nedeni, birden fazla karakter içeren tüm komutların, bir veya iki bayt boyutundaki belirteçlere sıkıştırılmasıdır.

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 sayesinde başka bir byte'ı traş ettin ! (ayrıca ondan 60’a 56’ya sıçradı.)


4
Ahhh, ilk programlama dilim. Nostalji için teşekkürler, haha.
Alex Pritchard

1
Yine de lise matematik dersi için TI programlıyor, testler ve ödevlerde sizin için hesaplayacak formüllerin oluşturulması çok yararlı.
Elias,

1
Etrafınızdakileri değiştirirseniz, cos(piAnsnumarayı başka bir bayttan tasarruf etmek için kullanabilirsiniz .
lirtosiast

9

Python 2, 115 bayt

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)

Gibi çağrı f("((()())()(()(())()))"), ve çıkış STDOUT.

açıklama

İle başlıyoruz n = 0. Giriş satırındaki her karakter için:

  • Char ise (, nboşluklar artar , sonra artırımn
  • Eğer karakter ise ), azalır ve nsonra nboşlukları hazırlarız.

Sonuç daha sonra sıkıştırılır ve yazdırılır. Python'un en kısa elemanın zipuzunluğuyla eşleştiğini unutmayın;

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

Genellikle , en uzun elemanın uzunluğunu doldurmak isterlerse itertools.zip_longest( izip_longest) kullanılır .zip

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

Ancak Python 2'de bu davranış haritalama yoluyla simüle edilebilir None:

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

Python 3, 115 bayt

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)

Sıkıştırma yok, sadece uygun şekilde doldurun ljust. Bu bir golf potansiyeli var gibi görünüyor.


8

R, 151 127 karakter

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

Girintiler ve yeni satırlarla:

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

Kullanımı:

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

Bu, tek bir karakter, bir vektör olarak böler, Standart girdi olarak dizesini okur kümülatif toplamını hesaplar (ve )böylece her bir parantez "seviye" işlem (gecikmeli) ikincisininde substracts. Daha sonra, her bir seviye için karşılık gelen parantezleri veya boşlukları içeren stdout'a yazdırır.

@MickyT'ye, kısaltmamı sağladığı için teşekkürler!


2
+1 Güzel ve zarif bir çözüm. Sen değiştirerek 6 kaydedebilirsiniz for(i in n)cat(ifelse(D[i]-j," ",S[i]));cat("\n")ile X=S;X[which(D!=j)]=' ';cat(X,sep='',fill=T). O zaman ngerçekten gerekli değil, ama biraz cumsum kısmını değiştirmeniz gerekir. D=c(C(S=="("),0)-c(0,C(S==")"));135'e
düşürüyor

@MickyT vay teşekkürler! bunu düşünmedim. whichburada gerçekten gerekli değildir ( D!=jzaten indekslemeye izin veren bir boole vektörü olmak). Ben tartışmayı bilmiyordum filliçin cat, bu şık hile! Beni şaşırtıcı 24 karakterle kısalttığın için teşekkürler !!
plannapus

8

C, 58 53 52 51 49 bayt

İmleç konumunu hareket ettirmek için ANSI çıkış dizilerini kullanır.

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

Gcc veya \eonu destekleyen başka bir derleyici kullanılmıyorsa, \x1Btoplam 2 ekstra byte ile değiştirilebilir. \e[Aimleci bir satır yukarı \e[B, imleci bir satır aşağı hareket ettirir. Kullanımı gerekli değil \e[BASCII dikey sekme karakteri kullanmayı iki bayt olarak kısaltılarak bir satır aşağı taşımak için 0xBveya \v.

Girdi dizgisinin, sorudan, sadece (dengeli) parantez içerdiği varsayılmaktadır, bu nedenle karakterin paritesini kontrol &1etmek ile (ve arasındaki farkı belirlemek yeterlidir ).


7

Pip, 53 bayt

Pip , icatımın kod-golf dilidir. İlk versiyon Cumartesi günü yayınlandı, bu yüzden resmen bir tur atabilirim! Aşağıdaki çözüm, golf dilleri gittikçe fazlasıyla rekabetçi değil, ama bunun nedeni kısmen, henüz zip ve max gibi şeyler uygulamadım.

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

Parantez dizesini komut satırı argümanı olarak bekler.

"Ungolfed" versiyonu:

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

Açıklama:

Çoğu golf dilinden farklı olarak, Pip, infix operatörleri için zorunludur, bu nedenle sözdizimi C ve türevlerine biraz daha yakındır. Ayrıca işlevsel ve dizi tabanlı programlardan fikir alır. Daha fazla dokümantasyon için depoya bakın.

Program ilk önce zbir işlevi girdi dizgisine eşleyerek derinliklerin bir listesini (içine kaydederek) oluşturur a. Global değişken vmevcut seviyeyi takip eder. ( Pip'deki a-gdeğişkenler işlev-yerel değişkenlerdir, ancak h-zgeneldir. vKullanışlı olduğundan -1'e önceden başlatılmıştır.)

Daha sonra, Wher satır oluşturmak ve yazdırmak için oluşturulan satır tüm boşluklardan oluşana kadar bir hile döngüsü kullanıyoruz . vşimdi sütunlar ve isatırlar için kullanılır . {z@++v=i?as}Defalarca orijinal giriş dizesi eşleştirilmiş fonksiyonu, geçerli satır olsun testler isatırı ile eşleşir cari parantez (saklanan olarak olması gerekiyordu zlistesi). Eğer öyleyse, parantezi ( a) kullanın ; değilse, kullanın s(boşluğa önceden başlatılmış). Sonuçta, her yinelemede, oçıktının bir sonraki satırına denk bir karakter listesi atanır.

Döngüye devam edip etmeyeceğimizi test etmek oiçin tüm boşlukların RMboş olup olmadığını kontrol ederiz . Değilse, yazdırın (varsayılan olarak her şeyi CJam'daki gibi bir araya getirir), sütun numarasını -1 olarak sıfırlayın ve satır numarasını artırın.

(Eğlenceli gerçek: İlk başta 51 baytlık bir çözüme sahiptim ... işe yaramadı, çünkü tercümanda bir hata oldu.)


7

Pyth, 31 bayt

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

Çevrimiçi deneyin.

-/<zk\(/<zhk\): Mevcut karakter pozisyonu için uygun seviyeyi bulur.

?YqN-/<zk\(/<zhk\)d: Uygun seviye mevcut seviye değilse, boşluk mevcut karakter ise boşluk.

Js.e?YqN-/<zk\(/<zhk\)dz: Dize oluşturun, kaydedin J.

I-JdJ: JTüm boşluklar değilse, yazdırın.

Vz: Döngü zzamanları.


6

GNU Bash + coreutils + girinti, 135

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

STDIN / STDOUT aracılığıyla giriş / çıkış:

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

indentağır kaldırma işleminin çoğunu yapar, ancak pens yerine diş teli ile çalışmak gerekir. Gerisi çıktısını devretmek için bu cevabın değiştirilmiş halidir 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)

Satır satır yazdırır. Belirli bir satır numarası için i(aslında, olumsuzlama), giriş dizgisinden geçer sve zyalnızca sderinlemesine karakterleri içeren yeni bir dize oluşturur i. Bu arttırılması veya azaltılması suretiyle yapılır iakım derinliği izlemek için ve ne zaman geçerli karakterleri ekleyerek iedilir 0parantez türü için ayarlanır, aksi takdirde bir boşluk ekleyerek.

Ardından, igeçerli satırın tamamı boşluk olmadıkça bir sonrakine yazdırır ve tekrar çeker . Parenler dengeli olduğundan, ibir döngü sonrası başlangıçtakiyle aynıdır.

Python 3, bir karakter haricinde aynı olurdu print(z).


5

hile :( Retina + TeX, N bayt hile :(

Bu, yalnızca MathJax veya şu anda bu SE için devre dışı bırakılmış diğer bazı TeX'leri kullanarak çıktı oluşturduğunuzda (?) Çalışır.

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

Her satır farklı bir dosyada olmalıdır, ancak Retina -e "\(" -e "({" -e "\)" -e "})" -e "\{\(" -e "_{("(veya eşdeğer sed komutunu sed -e "s/(/({/g;s/)/})/g;s/{(/_{(/g") kullanarak test edebilirsiniz . Giriş STDIN'den geçirilir.

Bu, her bir parantez çiftinin içeriğini parantez içine alarak ve sonra içindeki tüm öğeleri abone ederek çalışır.

Çıktı

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

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

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

TeX Çıkışı


1
Retina'yı kullandığınız için çok mutluyum ve bu durum kutunun dışında güzel bir fikir ama çıktının neye benzemesi gerektiği gibi değildi. ;) Özellikle bu, alternatif formülasyonu ihlal ediyor "Buna bakmanın bir başka yolu, n derinliğindeki parantezlerin yatay konumlarını koruyarak n satırına taşınmasıdır." Saf, kurala uyumlu bir Retina çözümünden çok etkilenmiştim ve bunun için bir ödül verebilirdi . ;)
Martin Ender

In total the lines must not be longer than twice the length of the input string. Satır 2'yi (\,{ve satır 4'ü değiştirmek }\,), çıktının buna uyması anlamına gelir (dikey derinlik hala yanlış olsa da: ()
user22723 0

Şey, kurallara uygun bir çözüm
üretmeyi başardım:)

1
İyi iş. Sanırım bu hile cevabını şimdi silebileceğin anlamına geliyor. ;)
Martin Ender

5

Java, 232 226 224 222 bayt

Golf versiyonu:

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

Uzun versiyon:

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

İlk önce girdi dizesi analiz edilir, bir sayaç eklemek / çıkarmak ve parantezlerin ne kadar derine ineceğini ve aynı zamanda en derin olanın ne kadar derin olduğunu takip ederek değerini saklamak için "(" ve ")" aranır. Sonra dizi analiz edilir; daha düşük değerlere sahip parantezler önce basılır ve en yüksek seviyeye ulaşana kadar satır satır yazdırmaya devam eder.

Muhtemelen bunu daha sonra golf oynamak için yollar bulacağım.


5

Javascript / ES6, 97 karakter

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

kullanım

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

açıklama

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

Bunun yerine, 1 bayt kazandıran n<m?console.log(o):0kullanabilirsiniz n<m&&console.log(o).
Ismael Miguel,

4

CJam, 43 41 36 bayt

Çok golf oynamıyorum (sanırım), ama işte ilk girişimim:

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

Nasıl çalışır

Çok kullanışlı bir gerçeği kullanıyorum )ve (CJam'da sırasıyla artış ve azalma anlamına geliyor. Böylece, derinliği elde etmek için dirsekleri değerlendiririm.

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";

Burada çevrimiçi deneyin


4

Octave, 85 karakter

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 ve Octave için oldukça doğal olan naif yaklaşımın optimizasyonu:

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;

Tablo t henüz mevcut olmayabilir ve herhangi bir öğeye hemen atayabiliriz ve bu öğenin olması için gerekli olan en uygun boyuta yeniden şekillenir.


4

Perl, 91 89 88 84 80 79 bayt

$t=<>;{$_=$t;s/\((?{$l++})|.(?{--$l})/$^R==$c?$&:$"/ge;print,++$c,redo if/\S/}
  • $ t giriş dizesidir.
  • $ c geçerli satırda yazdırmak istediğimiz derinliktir.
  • $ l, bir paren ile karşılaştıktan sonra bulunduğumuz derinliktir.
  • $ l, regex gömülü kod bloklarında güncellendi .
  • $ ^ R, en son kod bloğunun sonucudur.

4

Haskell, 154 bayt

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

diğer Haskell çözümü ile aynı fikir, ancak biraz daha kısa. - kullanım:

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

3

J, 46

Diğer 'golf dilleri' kadar iyi değil, ama savunmamda: J karakterlerle korkunç.

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

Dizeyi bir işlev için girdi olarak alır. J'de yapmanın daha iyi bir yolu da var.

Kullanımı:

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

Bunu J.'de yapmanın başka bir yolu için cevabımı görün
FUZxxl

3
Şahsen, ben J dizeleri için mükemmel uygun olduğunu düşünüyorum. Sadece dizilerle düşünmelisin.
FUZxxl

3

Ruby, 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]}}

Açıklama:

->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 bayt

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

Girintili'ye:

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

Son döngü kısaltılabilir sanırım, ama onu okuyucuya bir egzersiz olarak bırakacağım. ;-)


Eski, 233 baytlık cevap:

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

Girintili'ye:

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

Bir yıldan fazla geçtiğini biliyorum, ancak "Son döngü kısaltılabilir sanırım, ama onu okuyucuya bir egzersiz olarak bırakacağım. ;-)"; gerçekten haklısın. Bu değiştirilebilir for(x=0;x<l*l;x++)System.out.print((x%l==0?"\n":"")+m[x]);için for(x=0;x<l*l;)System.out.print((x%l==0?"\n":"")+m[x++]);-1 bayt için. Ayrıca, alanları kaldırarak p=x=0yalnızca int p=0,x=0,alanları başlatarak kullanıp kaldırarak 2 bayt daha tasarruf edebilirsiniz . Toplamda 211 bayt olur .
Kevin Cruijssen

3

C #, 195 bayt

Önce golf denemeye - yanlış bir şey yaptıysam bağırma.

SetCursorPosition kullanarak ve girişi komut satırı argümanı olarak alarak soldan sağa çalışan alternatif C # sürümü.

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

Yazma konumunu açık / kapalı paren temelinde değil, tam satırlara göre ayarlamanın eğlenceli olacağını düşündüm. Pareni kapat, yazmadan önce pozisyonu yukarı taşır; open paren yazdıktan sonra aşağı taşır. SetCursorPosition eylemi beş bayttan tasarruf sağlar. İmleci, çıktıdan sonra bir sonraki satıra taşımak, biraz fazladan alacaktır.

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

Toplu İş, 356 335 bayt

Bu zorluk için zaten bir Batch çözümü bulunduğunu biliyorum, ancak bu önemli ölçüde daha fazla golf oynuyor ve farklı bir yaklaşım izliyor gibi görünüyor. En önemlisi, diğer toplu çözüm en az bir powershell komutu içeriyor; bu çözüm değil.

@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.)

Noktayı U+0008takip eden ikinci ve son satırda bir geri alma karakteri ( ) vardır (satır 12, sütun 57). Bu, burada gönderilen kodda görünmez ancak bayt sayısına dahildir.


Başka biri aslında Batch - Nice one +1'e bir cevap gönderiyor.
unclemeat

3

Toplu, 424 bayt

@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!

Un-golfed:

@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!

Örnek:

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

3

C, 118 117 Bayt

C'de başka bir cevap var, ama benimki daha kısa.

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

Ungolfed versiyonu:

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

Ve çalışıyor!

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

1
Oldukça şık bir çözüm, ancak putchar(c-d?32:*p)bir karakterden daha kısa putchar(c==d?*p:32).
pawel.boczarski

2

Haskell, 227 bayt

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
Operatörlerle birkaç yerden tasarruf edebilirsiniz: ör. n#[]Yerine m n [].
Franky

2

Perl, 76 bayt

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

use strictBurada yok :)


2

Lex, 94 bayt

Linux konsol kodlarına bağlıdır. Gcc ile, her iki örneğini de \33gerçek bir kaçış karakteriyle değiştirerek dört baytı kesebilirsiniz .

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

Derlemek ve çalıştırmak için:

$ flex -o telescopic.c telescopic.l
$ gcc -o telecopic telescopic.c -lfl
$ ./telescopic
(()(()())()((())))(())
(                )(  )
 ()(    )()(    )  ()
    ()()    (  )
             ()
--- type ctrl-D ---
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.