Chuỗi địa hình


23

Dưới đây là một số ví dụ đầu vào, vì vậy tôi có thể giải thích vấn đề là gì:

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

Hãy nghĩ về dòng văn bản này như một bản đồ địa hình của một số ngọn núi. Mỗi bộ dấu ngoặc đơn minh họa một đơn vị độ cao.

Nếu chúng ta "xem" cái này từ bên cạnh, để chúng ta nhìn thấy những ngọn núi theo chiều dọc, chúng ta sẽ thấy:

          4 5                cherries    woohoo  
  1 2  3       moo       lik          e
                      i

Cho một trong những bản đồ địa hình này, xuất bản đồ, nhưng theo tỷ lệ dọc, giống như đầu ra ở trên. Sắp xếp các mục khác nhau trong bản đồ với số lượng ký tự cho mục tiếp theo. Ví dụ, có 4 khoảng trắng ở đầu ra giữa mooi. Tương tự như vậy, có 4 ký tự ở đầu vào giữa mooi.

Mã nào thực hiện điều này với số lượng ký tự ít nhất sẽ thắng.


Có an toàn không khi cho rằng chiều cao sẽ luôn tích cực? Ví dụ: đầu vào ((1 2))))))))))3không hợp lệ nếu độ cao âm bị cấm.
Cristian Lupascu

@ w0lf: vâng, dấu ngoặc đơn sẽ luôn khớp với nhau.
beary605

Câu trả lời:


10

J, 87 79 72 70 67 57 56 ký tự

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

Lấy đầu vào từ bàn phím. Thí dụ:

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

Giải trình:

Giải thích này dựa trên phiên bản đầu tiên của chương trình của tôi:

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

x=.1!:1[1lấy đầu vào từ bàn phím và đặt nó vào xsau

(('('&([:+/=)-')'&([:+/=))\,.i.@#)tạo một danh sách tất cả các phân vào chuỗi ( i.@#) và khâu ( ,.) nó cùng với kết quả của (('('&([:+/=)-')'&([:+/=))\động từ.

(('('&([:+/=)-')'&([:+/=))\động từ này được áp dụng cho tất cả các tiền tố của chuỗi (để trên đầu vào hellonó sẽ áp dụng cho h, he, hel, hell, và hello. Nó là một ngã ba , mà đếm số dấu ngoặc mở ('('&([:+/=)và sau đó trừ đi số lượng khung gần ')'&([:+/=). Điều này cho phép tôi danh sách của các phân vào chuỗi và mức ký tự ở chỉ mục đó sẽ ở đầu ra. Trên đầu vào đơn giản, điều này cho tôi như sau:

   (('('&([:+/=)-')'&([:+/=))\,.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

((' '$~{.@]),[{~{:@])"1đây là một động từ lấy danh sách tôi vừa tạo và cũng là đầu ra của ('( ) 'charsub x)(chỉ thực hiện thay thế chuỗi để thay thế tất cả các dấu ngoặc có khoảng trắng trong x). Nó lấy đuôi của từng mục trong danh sách {:@]và sử dụng nó làm chỉ mục vào chuỗi để lấy ký tự [{~{:@]. Sau đó, nó đặt tiền tố ,với số lượng khoảng trắng được chỉ định bởi phần đầu của mỗi mục trong danh sách (' '$~{.@]). Trong ví dụ trước, điều này mang lại cho tôi:

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

 o
 n
 e

  t
  w
  o

   t
   h
   r
   e
   e

Sau đó tôi chuyển mảng |:và đảo ngược nó |.để có được đầu ra mong muốn.


6

GolfScript 69

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

Demo trực tuyến tại đây .

Giải trình:

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 Vâng, cả hai chúng tôi đều làm :)
Cristian Lupascu

Quan tâm để thêm một lời giải thích làm thế nào nó hoạt động?
Timwi

@Timwi Tôi đã chỉnh sửa câu trả lời của mình để đưa ra lời giải thích
Cristian Lupascu

5

APL (59)

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

Tôi đã giả định rằng 'cơ sở' cũng cần phải có thể sử dụng được. (tức (a(b))c(d)là hợp lệ). Nếu điều này là không cần thiết, hai ký tự có thể được lưu.

Giải trình:

  • T←⍞: lưu trữ một dòng đầu vào trong T
  • '()'∘=¨T: cho mỗi ký tự trong T, xem đó là dấu ngoặc đơn mở hay đóng. Điều này đưa ra một danh sách các danh sách các booleans.
  • 1 ¯1∘ר: nhân phần tử thứ hai trong mỗi danh sách này với -1 (vì vậy dấu ngoặc đơn mở là 1, đóng là -1 và bất kỳ ký tự nào khác là 0).
  • +/¨: lấy tổng của từng danh sách bên trong. Bây giờ chúng ta có giá trị ∆y cho mỗi ký tự.
  • P←: cửa hàng ở P.
  • R←1++\P: lấy tổng số P đang chạy, đưa ra chiều cao cho mỗi ký tự. Thêm một cho mỗi ký tự để các ký tự bên ngoài dấu ngoặc đơn nằm trên dòng đầu tiên.
  • (⍴T)∘⍴¨⍳⌈/R: với mỗi giá trị y có thể, hãy tạo một danh sách miễn là T, chỉ bao gồm giá trị đó. (tức là 1111 ..., 2222 ...., v.v.)
  • R∘=¨: cho mỗi phần tử trong danh sách này, hãy xem liệu nó có bằng R. (Đối với mỗi cấp độ, chúng tôi hiện có một danh sách các số 0 và các phần tử tương ứng với việc một ký tự có xuất hiện ở cấp đó hay không).
  • ⍵×P=0: cho mỗi danh sách này, đặt nó thành 0 nếu P không bằng 0 tại điểm đó. Điều này được loại bỏ các ký tự có delta-y khác không, để thoát khỏi dấu ngoặc đơn.
  • ⊃,/T\¨⍨: cho mỗi độ sâu, chọn từ T các ký tự sẽ xuất hiện.
  • ⊖↑: tạo một ma trận và đặt nó ở bên phải.

Bạn đang sử dụng triển khai APL nào? Nó có miễn phí không?
FUZxxl

@FUZxxl Tôi đã sử dụng Dyalog APL, phiên bản Windows có thể được tải xuống miễn phí.
bến

5

Tcl, 50

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

Loại gian lận, nhưng tốt ..

Tôi sử dụng trình tự thoát ascii để có được sự khác biệt dòng, ^[[Acó nghĩa là di chuyển con trỏ 1 dòng lên, ^[[Blà di chuyển con trỏ 1 dòng xuống.


5

APL, 41 ký tự / byte *

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

Đã thử nghiệm trên Dyalog, với một ⎕IO←1⎕ML←3môi trường. Đây là một chức năng lấy đầu vào cần thiết và trả về đầu ra. Với cách diễn đạt câu hỏi, tôi tin rằng nó có thể chấp nhận được. Trong trường hợp không phải, đây là phiên bản đọc từ stdin và ghi vào thiết bị xuất chuẩn, để biết thêm 4 ký tự:

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

Giải thích :

{                                 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

Ví dụ:

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 có thể được lưu trong nhiều bộ ký tự byte đơn kế thừa, ánh xạ các ký hiệu APL lên 128 byte trên. Do đó, với mục đích chơi gôn, một chương trình chỉ sử dụng các ký tự ASCII và các ký hiệu APL có thể được ghi là chars = byte.


Tôi đang tìm kiếm ký tự APL được đặt ở đây và tôi không thể tìm thấy biểu tượng. Nó trông giống như một sự kết hợp của ¨và các ~nhân vật?
Gareth

Xin chào @Gareth Không, nó không có trong IBM APL2. Bạn có thể tìm thấy nó trong Dyalog (thương mại, nhưng có phiên bản nagware được chôn trong trang web của họ và đủ tốt để chơi gôn; IMHO APL tốt nhất hiện nay), Nars2000 (APL mã nguồn mở tốt nhất), APLngn APL , trong số đó khác.
Tobia

@Gareth Về mặt đồ họa, đó là sự kết hợp của ~¨, mặc dù đó là một nhân vật khác với cả hai. Đó là một toán tử được gọi là Commute . Ở dạng dyadic, nó lật các đối số của hàm dyadic được áp dụng cho : (5-2)=(2-⍨5). Là một toán tử đơn trị, nó biến một hàm dyadic thành monadic, sao chép đúng đối số : (2*2)=(*⍨2). Nó chủ yếu được sử dụng để viết một dòng chức năng không bị gián đoạn từ phải sang trái, mà không phải đặt dấu ngoặc đơn xung quanh các biểu thức lớn và đảo mắt xung quanh chúng. Trong chơi gôn, nó hữu ích vì 3*⍨1-2ít hơn một char (1-2)*3:-)
Tobia

2
Vậy nó tương đương với ~J rồi.
Gareth

3

J, 56 ký tự

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

Một giải pháp J gồm 56 ký tự khác ... Tôi đếm độ sâu bằng cách dịch (thành ⁻1, )thành 1 và tất cả các ký tự khác thành 0, và sau đó lấy tổng của việc này : [: +/\ 1 _1 0 {~ '()'&i.. Phần còn lại phần lớn tương tự như giải pháp của @ Gareth.


2

Python, 161 ký tự

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

Con trăn, 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

Hồng ngọc 1.9 (129)

Đọc từ stdin.

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
Tốt đẹp! bạn đã phát hiện ra một lỗi trong công cụ tô sáng Ruby :)
Cristian Lupascu

Tôi đã thử nghiệm và tô sáng SQL hoạt động tốt hơn cho chương trình của bạn.
Cristian Lupascu

@ w0lf ha, bạn nói đúng. Tôi đã thay đổi //để ''giữ cho nhân vật đếm giống nhau và tránh lỗi trong công cụ tô sáng.
Paul Prestidge

2

C, 132 ký tự

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

Mô tả không thể xác định số lượng đầu vào phải chấp nhận để được chấp nhận, vì vậy tôi đã giải quyết các giới hạn phù hợp nhất với nhu cầu chơi gôn của mình (trong khi vẫn hoạt động với đầu vào ví dụ cụ thể). Cho phép tôi nhân cơ hội này để nhắc nhở mọi người rằng thường là một ý tưởng tốt để chỉ định mức tối đa tối thiểu trong các mô tả thử thách của bạn.

Có hai vòng lặp chính trong mã. Vòng lặp thứ nhất đưa ra tất cả các ký tự không dấu ngoặc đơn cho dòng đầu ra thích hợp và vòng lặp thứ hai in mỗi dòng.


1

C, 149 ký tự

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

chạy với trích dẫn arg, egaout "((1 2) (3 (4 5) moo)) (i (like (cherry) e (woohoo)))"



0

C #, 229 byte

Nếu không có giới hạn về không gian dọc dẫn đầu, bạn có thể sử dụng điều này (thụt lề cho rõ ràng.) Nó sẽ khởi tạo con trỏ xuống một dòng cho mỗi lần (tìm thấy trước khi in, sau đó di chuyển con trỏ lên và xuống khi đọc dấu ngoặc.

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 byte

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

Hãy thử trực tuyến!

Tác dụng phụ: Chars &'thay đổi chiều cao như (), nhưng màn hình. So sánh kết quả cho:

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

Ít chơi gôn hơn:

$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 (Dành cho S & G)

Không phải là đẹp nhất của mã.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.