Topografik Dizeler


23

İşte bazı örnek girdiler, yani sorunun ne olduğunu açıklayabilirim:

((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))

Bu metin satırını bazı dağların topografik bir haritası olarak düşünün. Her parantez seti bir irtifa birimini gösterir.

Bunu yandan görürsek, dağları dikey olarak görürüz, göreceğiz:

          4 5                cherries    woohoo  
  1 2  3       moo       lik          e
                      i

Bu topografik haritalardan birine bakıldığında, haritanın çıktısını alın, ancak yukarıdaki çıktıdaki gibi dikey bir ölçekte. Haritadaki farklı öğeleri karakter sayısı ile sonraki öğeye ayırın. Örneğin, çıktıda moove arasında 4 boşluk vardır i. Aynı şekilde, girişinde moove arasında 4 karakter vardır i.

Bunu en az sayıda karakter yapan kod kazanır.


Yüksekliklerin her zaman pozitif olacağını varsaymak güvenli midir? Örneğin, ((1 2))))))))))3negatif yükseklikler yasaksa giriş geçersiz olmalıdır.
Cristian Lupascu

@ w0lf: evet, parantez her zaman eşleşir.
beary605

Yanıtlar:


10

J, 87 79 72 70 67 57 56 karakter

'( ) 'charsub|.|:(+/\@('('&=-')'&=)(],~' '$~[)"0])1!:1[1

Klavyeden girdi alır. Örnek:

   '( ) 'charsub|.|:(+/\@('('&=-')'&=)(],~' '$~[)"0])1!:1[1
((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))
          4 5                cherries    woohoo
  1 2  3       moo       lik          e
                      i

Açıklama:

Bu açıklama programımın ilk versiyonuna dayanıyor:

|.|:('( ) 'charsub x)((' '$~{.@]),[{~{:@])"1(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1

x=.1!:1[1klavyeden giriş almak ve xdaha sonra kullanmak

(('('&([:+/=)-')'&([:+/=))\,.i.@#)tüm iç dizilerin bir listesini oluşturur ( i.@#) ve fiilin ,.sonucu ile birlikte dize diker ( ) (('('&([:+/=)-')'&([:+/=))\.

(('('&([:+/=)-')'&([:+/=))\Bu fiil (böylece girişinde dize önekleri tüm uygulanır hellobunun geçerli olacak etmek h, he, hel, hell, ve hello. Bu bir olan çatal açık parantez sayar, ('('&([:+/=)sonra da kapat parantez sayısını çıkarır ')'&([:+/=). Bu bana listesini verir dize içine indeces ve o indeksteki karakterin çıktıda olması gereken seviye Basit girişlerde bu bana aşağıdakileri verir:

   (('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
(one(two(three)))
1  0
1  1
1  2
1  3
2  4
2  5
2  6
2  7
3  8
3  9
3 10
3 11
3 12
3 13
2 14
1 15
0 16

((' '$~{.@]),[{~{:@])"1Bu sadece yeni oluşturduğum listeyi ve çıktılarını ('( ) 'charsub x)(ki tüm parantezleri boşluklarla değiştirmek için bir dize değiştirme yapan) alan bir fiildir x. Listedeki her öğenin kuyruğunu alır {:@]ve karakteri almak için dizgede bir dizin olarak kullanır [{~{:@]. Ardından ,listedeki her bir öğenin başı tarafından belirtildiği gibi boşluk sayısıyla onu ön ekler (' '$~{.@]). Önceki örnekte bu bana verir:

   ('( ) 'charsub x)((' '$~{.@]),[{~{:@])"1(('('&([:+/=)-')'&([:+/=))\,.i.@#)x=.1!:1[1
(one(two(three)))

 o
 n
 e

  t
  w
  o

   t
   h
   r
   e
   e

Sonra diziyi |:çevirip |.istenen çıktıyı elde etmek için tersine çeviriyorum .


6

GolfScript 69

0:§;{.'()'?))3%(.§+:§' ':s*\@s\if\n}%n/.{,}%$)\;:μ;{.,μ\-s*\+}%zip n*

Online demo burada .

Açıklama:

0:§;                # declare the variable §, representing the 
                    # current vertical level and initialize it at 0

{                   # iterate for each char in the string:

    .'()'?))3% (    # add on the stack the amount by which
                    # the current vertical level should be 
                    # adjusted:
                    #   * +1 if the character is '('
                    #   * -1 if the character is ')'
                    #   * 0 otherwise

    .§+:§           # adjust the value of §

    ' ':s*          # add as many spaces as § tells us
                    # and save the space in variable s

    \@s\if\         # return current char, if it's printable,
                    # or a space if it's '(' or ')'

    n               # add a newline char

}%

n/                  # split by newline char; now we have 
                    # an array of strings on the stack.
                    # Each string is a vertical line of the
                    # final output.

.{,}%$)\;:μ;        # Iterate through the strings and find the
                    # maximum length

{
    .,μ\-s*\+       # Add spaces at the end to make all the strings 
                    # the same length
}%

zip                 # Transpose the strings

n*                  # Join the transposed strings by newline characters

@Gareth Evet, ikimiz de :) :)
Cristian Lupascu

Nasıl çalıştığını bir açıklama eklemek ister misiniz?
Timwi

@Timwi Bir açıklama eklemek için cevabımı düzenledim
Cristian Lupascu

5

APL (59)

⊖↑{⊃,/T\¨⍨⍵×P=0}¨R∘=¨(⍴T)∘⍴¨⍳⌈/R←1++\P←+/¨1 ¯1∘ר'()'∘=¨T←⍞

Temelin de kullanılabilir olması gerektiğini kabul ettim. (yani (a(b))c(d)geçerli). Bu gerekli değilse iki karakter kaydedilebilir.

Açıklama:

  • T←⍞: T'de bir giriş satırı kaydet
  • '()'∘=¨T: T'deki her karakter için, bunun bir açılış veya kapanış parantezi olup olmadığına bakın. Bu, boolean listelerinin bir listesini verir.
  • 1 ¯1∘ר: Bu listelerin her birindeki ikinci elemanı -1 ile çarpın (yani bir açılış parantezi 1, bir kapanış olanı -1 ve diğer herhangi bir karakter 0'dır).
  • +/¨: her bir iç listenin toplamını alın. Artık her karakter için valuey değerimiz var.
  • P←: P. mağazasında
  • R←1++\P: her bir karakter için yükseklik vererek, toplam P koşusu alın. Her karaktere bir tane ekleyin, böylece parantez dışındaki karakterler ilk satırda olsun.
  • (⍴T)∘⍴¨⍳⌈/R: Her olası y-değeri için, sadece bu değerden oluşan, T ye kadar bir liste yapın. (ör. 1111, 2222, vb.)
  • R∘=¨: Bu listedeki her eleman için, R'ye eşit olup olmadığına bakın. (Her seviye için, bir sıfır listesi ve bir karakterin o seviyede görünüp görünmemesine karşılık gelenler var).
  • ⍵×P=0: bu listelerin her biri için, P o noktada sıfır değilse, sıfıra ayarlayın. Bu, sıfır olmayan bir delta-y ile karakterlerden kurtulmakta, böylece parantezlerden kurtulmaktadır.
  • ⊃,/T\¨⍨: her derinlik için görünmesi gereken karakterleri T arasından seçin.
  • ⊖↑: bir matris oluşturmak ve yukarı doğru koymak.

Hangi APL uygulamasını kullanıyorsunuz? Bedava mı
FUZxxl

@ FUZxxl Ben Dyalog APL kullanıyorum, Windows sürümü ücretsiz indirilebilir.
marinus

5

Tcl, 50

puts \33\[9A[string map {( \33\[A ) \33\[B} $argv]

Hile yapmak, ama iyi ..

Satır farkını elde etmek için ascii kaçış dizilerini kullanıyorum, bunun ^[[Aanlamı imleci 1 satır yukarı ^[[Btaşı, imleci 1 satır aşağı taşı.


5

APL, 41 chars / bytes *

{⊖⍉⊃(↑∘''¨-⌿+/¨p∘.=,\⍵),¨⍵/⍨1-2×⍵∊p←'()'}

⎕IO←1Ve ⎕ML←3çevre ile Dyalog üzerinde test edilmiştir . Gerekli girişi alan ve çıktıyı döndüren bir fonksiyondur. Sorunun ifadesi göz önüne alındığında, kabul edilebilir olduğuna inanıyorum. Olmaması durumunda, 4 karakter için stdin'den okuyan ve stdout'a yazan bir sürüm:

⍞←⊖⍉⊃(↑∘''¨-⌿+/¨'()'∘.=,\a),¨a/⍨1-2×'()'∊⍨a←⍞

Açıklama :

{                                 p←'()'}  p is the string made of two parentheses
                                ⍵∊ ______  check which characters from ⍵ are parens
                            1-2× ________  -1 for every par., 1 for every other char
                         ⍵/⍨ ____________  replace () with spaces in the orig. string
    (                 ),¨ _______________  append every char to the following items
                   ,\⍵ _____________________  for every prefix of the original string
               p∘.= ________________________  check which chars are '(' and which ')'
            +/¨ ____________________________  sum: compute the number of '(' and ')'
          -⌿ _______________________________  subtract the no. of ')' from that of '('
     ↑∘''¨ _________________________________  generate as many spaces as that number
 ⊖⍉⊃ ____________________________________  make it into a table, transpose and flip

Örnekler:

topo '((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))'
          4 5                cherries    woohoo   
  1 2  3       moo       lik          e           
                      i                           

 

topo 'a  (  b ( c(d)e ) f  )  g'
            d            
          c   e          
      b           f      
a                       g

*: APL, APL sembollerini üst 128 bayta eşleyen çeşitli eski tek baytlık karakter kümelerine kaydedilebilir. Bu nedenle, golf oynamak amacıyla, yalnızca ASCII karakterlerini ve APL sembollerini kullanan bir program chars = bayt olarak puanlanabilir.


Burada ayarlanan APL karakterini arıyorum ve bulamıyorum . Bu bir kombinasyonu gibi görünüyor ¨ve ~karakterler?
Gareth,

Merhaba @Gareth Hayır, IBM APL2'de değildi. Bunu Dyalog'da bulabilirsiniz (ticari, ancak web sitelerinde gömülü bir nagware sürümü var ve golf oynamak için yeterince iyi; IMHO bugün mevcut olan en iyi APL), Nars2000 (en iyi açık kaynak APL), GNU APL ve ngn'in APL'si arasında diğerleri.
Tobia,

@Gareth Grafiksel olarak ~ve ¨her ikisinden de farklı bir karakter olmasına rağmen birleşimidir . Commute adında bir operatör . Onun diyadik formda o uygulandığından dyadic fonksiyonun argümanları çevirir: (5-2)=(2-⍨5). Birli operatörü olarak doğru bir argüman çoğaltarak, monadic içine diyadik fonksiyonunu açar: (2*2)=(*⍨2). Çoğunlukla, büyük ifadelerin etrafına parantez koymak ve gözlerinin etrafına atlamak zorunda kalmadan, kesintisiz bir işlev akışı sağdan sola yazmak için kullanılır. Golf oynamakta faydalıdır çünkü :-) ' 3*⍨1-2ten bir karakterden daha azdır(1-2)*3
Tobia

2
Öyleyse ~J'nin eşdeğeri .
Gareth,

3

J, 56 karakter

'( ) 'charsub|.|:((,~#&' ')"0[:+/\1 _1 0{~'()'&i.)1!:1]1

Başka 56 karakterlik J çözümü ... Ben çevirerek derinliğini saymak (, ⁻1 içine )0 içine 1 ve diğer tüm karakterlerin içine ve sonra bunun geçerli toplam alarak: [: +/\ 1 _1 0 {~ '()'&i.. Gerisi büyük ölçüde @ Gareth'in çözümüne benziyor.


2

Python, 161 karakter

S=raw_input()
R=range(len(S))
H=[S[:i].count('(')-S[:i].count(')')for i in R]+[0]
for h in range(max(H),0,-1):print''.join((' '+S[i])[H[i]==H[i+1]==h]for i in R)

2

Python, 130

a=[""]*9
l=8
i=0
for c in raw_input():o=l;l+=c==')';l-=c=='(';a[l]=a[l].ljust(i)+c*(o==l);i+=1
print"\n".join(filter(str.strip,a))

2

Yakut 1,9 (129)

Stdin'den okur.

l=0
$><<gets.split('').map{|c|x=[?(]*99;x[l+=c==?(?-1:c==?)?1:0]=c;x}.transpose.map(&:join).*(?\n).tr('()',' ').gsub(/^\s+\n/,'')

3
Güzel! Ruby fosforlu
kaleminde

Test ettim ve SQL vurgulama programınız için daha iyi çalışıyor.
Cristian Lupascu

@ w0lf ha, haklısın. Değiştim //için ''hangi karakter aynı çetelesini tutuyor ve fosforlu hatasından önler.
Paul Prestidge

2

C, 132 karakter

char*p,b[999];n;
main(m){for(p=gets(memset(b,32,999));*p;++p)*p-41?*p-40?p[n*99]=*p:++n>m?m=n:0:--n;
for(;m;puts(b+m--*99))p[m*99]=0;}

Açıklama, gönderimin kabul edilmek için ne kadar girdi kabul edeceğini belirleyemedi, bu yüzden golf oynama ihtiyaçlarıma en uygun limitleri belirledim (yine de bir örnek girdiyle çalışırken). Bu fırsatı, insanlara, meydan okuma açıklamalarınızda asgari maksimumları belirlemenin genellikle iyi bir fikir olduğunu hatırlatmama izin verin.

Kodda iki ana döngü var. İlk döngü, parantez dışındaki tüm karakterleri uygun çıktı satırına yönlendirir ve ikinci döngü her satırı yazdırır.


1

C, 149 karakter

#define S for(i=0;c=v[1][i++];)h+=a=c-'('?c-')'?0:-1:1,
c,i,h=0,m=0;main(int a,char**v){S m=h>m?h:m;for(;m;m--){S putchar(a||h-m?32:c);putchar(10);}}

"" ((1 2) (3 (4 5) moo)) (i (lik (kirazlar) e (woohoo)))) "ile belirtilen argüman ile koş


0

Octave, 128

Son cevabımı çok benzer ...

p=1;x=[0];y=input(0);for j=1:numel(y);p-=(y(j)==")");x(p,j)=y(j);p+=(y(j)=="(");end;x(x==40)=x(x==41)=x(x==0)=32;char(flipud(x))

Ölçek

Giriş: "((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))"

Çıktı:

          4 5 kiraz woohoo   
  1 2 3 ay önce           
                      ben                           

0

C #, 229 bayt

Öndeki dikey boşlukta herhangi bir kısıtlama yoksa, bunu kullanabilirsiniz (netlik için girintili). (Yazdırmadan önce bulunanlar için imleci bir satır aşağı doğru başlatır , sonra imleci yukarı oklar ve aşağıya hareket ettirir.

using C=System.Console;
class P{
    static void Main(string[]a){
        int l=a[0].Length,i=l;
        while(i>0)
            if(a[0][--i]=='(')C.CursorTop++;
        while(++i<l){
            char c=a[0][i];
            if(c=='('){
                c=' ';
                C.CursorTop--;
            }
            if(c==')'){
                c=' ';
                C.CursorTop++;
            }
            C.Write(c);
        }
    }
}

0

PowerShell , 120 119 bayt

(($h=($c=$args|% t*y)|%{($l+=(1,-1)[$_-40])})|sort)[-1]..0|%{$x=0;$y=$_
-join($c|%{"$_ "[$h[$x++]-ne$y-or$_-in40,41]})}

Çevrimiçi deneyin!

Yan etkileri: Chars &ve 'olarak yüksekliğini değiştirir (ve )ancak görüntüler. Şunun için sonuçları karşılaştır:

&$f "((1 2)(3 (4 5) moo)) (i (lik(cherries)e (woohoo)))"
&$f "&&1 2'&3 &4 5' moo'' &i &lik&cherries'e &woohoo'''"

Daha az golf oynadı:

$chars=$args|% toCharArray

$heights=$chars|%{
    $level+=(1,-1)[$_-40]       # 40 is ASCII for '(', 41 is ASCII for ')'
    $level
}

$maxHeight=($heights|sort)[-1]

$maxHeight..0|%{
    $x=0;$y=$_
    $line=$chars|%{
        "$_ "[$heights[$x++]-ne$y -or $_-in40,41]
    }
    -join($line)
}

-1

VB.net (S&G İçin)

En güzel kod değil.

Module Q
 Sub Main(a As String())
  Dim t = a(0)
  Dim h = 0
  For Each m In (From G In (t.Select(Function(c)
                                     h += If(c = "(", 1, If(c = ")", -1, 0))
                                     Return h
                                   End Function).Select(Function(y, i) New With {.y = y, .i = i}))
             Group By G.y Into Group
             Order By   y Descending
            Select Group.ToDictionary(Function(x) x.i)
               ).Select(Function(d) New String(
                          t.Select(Function(c,i)If(d.ContainsKey(i),If(c="("c Or c=")"c," "c,c)," "c)).ToArray))
   Console.WriteLine(m)
  Next
 End Sub
End Module
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.