Kiểm tra cú pháp mở đầu


10

Mở đầu là một ngôn ngữ lập trình bí truyền, có rất ít, nhưng bất thường, những hạn chế về những gì cấu thành một chương trình hợp lệ. Bất kỳ khối văn bản ASCII có thể in nào ("khối" có nghĩa là các dòng của ASCII có thể in được phân tách bằng các dòng mới - 0x0A) là hợp lệ với điều kiện:

  • Mỗi cột (dọc) của văn bản chứa tối đa một ().
  • Bỏ qua vị trí thẳng đứng của chúng, ()được cân bằng, nghĩa là, mỗi cái (được ghép với chính xác một )bên phải của nó và ngược lại.

Viết chương trình hoặc hàm, được cung cấp một chuỗi chứa ASCII có thể in và dòng mới, xác định xem nó có cấu thành chương trình Prelude hợp lệ hay không. Bạn có thể nhận đầu vào thông qua STDIN (hoặc thay thế gần nhất), đối số dòng lệnh hoặc đối số hàm. Kết quả có thể được trả về hoặc in thành STDOUT, sử dụng bất kỳ hai giá trị trung thực / giả mạo cố định nào bạn chọn.

Bạn không được cho rằng đầu vào là hình chữ nhật.

Đây là mã golf, vì vậy bài nộp ngắn nhất (tính bằng byte) sẽ thắng.

Ví dụ

Sau đây là các chương trình Prelude hợp lệ (trên thực tế, chúng thậm chí các chương trình Prelude thực sự ):

?1-(v  #1)-             
1   0v ^(#    0)(1+0)#)!
    (#)  ^#1-(0 #       
1(#  1) v #  - 1+)
    vv (##^v^+
? v-(0 # ^   #)
?
  1+              1-!

Và đây là một số đầu vào, tất cả đều không hợp lệ :

#(#(##)##)##(
)##(##(##)#)#
#(#)
)###
#(##
(##)
(##)
(#)#
(##)
(###
#(#)
(##)
#(#)
###)
#()#
()##
#(#)##
###
###(#)

Prelude có bình luận nào có thể ngăn chặn một paren gần không?
Alex A.

@Alex Không. Các quy tắc trên thực sự là tất cả để quyết định xem một chương trình có hợp lệ hay không.
Martin Ender

Thật tuyệt, cảm ơn vì đã làm rõ. Chỉ muốn chắc chắn.
Alex A.

Quy tắc 1 - "Mỗi cột văn bản chứa nhiều nhất một (và)"; Ví dụ 1, dòng 2: "1 0v ^ (# 0) (1 + 0) #)!" -> Tôi thấy 3 )và 2 (. Không nên chỉ là 1 trên mỗi dòng?
Ismael Miguel

1
"Cột" @IsmaelMiguel thường được hiểu là dùng để chỉ các đường thẳng đứng (đặc biệt là trong bối cảnh của lưới). Dù sao thì tôi cũng đã làm rõ rồi.
Martin Ender

Câu trả lời:


3

CJam, 57 56 byte

qN/z_{_"()"--W<},,\s:Q,{)Q/({_')/,\'(/,-}:T~\sT0e>+z+}/!

Quá lâu, có thể chơi golf rất nhiều. Giải thích để được thêm một khi tôi chơi nó.

Giải thích ngắn gọn

Có hai kiểm tra trong mã:

  • Bộ lọc đầu tiên kiểm tra rằng mỗi cột có tối đa 1 khung. Đầu ra cuối cùng của bộ lọc là số lượng cột có nhiều hơn 1 dấu ngoặc.
  • Thứ hai, chúng tôi chuyển đổi đầu vào thành định dạng chính của cột và sau đó chia nó trên mỗi chỉ mục thành hai phần.
    • Trong mỗi hai phần này, ( Number of "(" - Number of ")") nên khen nhau. Vì vậy, khi bạn thêm chúng lên, nó sẽ dẫn đến 0. Bất kỳ phần nào không có thuộc tính này làm cho toàn bộ đầu vào có dấu ngoặc không khớp.
    • Tôi cũng phải đảm bảo rằng "(" nằm ở bên trái của ")". Điều này có nghĩa là giá trị Number of "(" - Number of ")"không thể âm đối với khối bên phải.

Dùng thử trực tuyến tại đây


6

Python 2, 128 119 105 byte

def F(p):
 v=n=1
 for r in map(None,*p.split("\n")):A,B=map(r.count,"()");n+=B-A;v*=n<2>A+B
 return n*v>0

Bạn có biết rằng bạn có thể ánh xạ Không có trong Python 2 không?

Giải trình

Chúng tôi muốn bắt đầu bằng cách hoán đổi khúc dạo đầu để các cột trở thành hàng. Thông thường chúng ta sẽ làm điều này với zip, nhưng vì zipcắt ngắn đến chiều dài hàng ngắn nhất và itertools.zip_longestquá dài cho môn đánh gôn, có vẻ như không có cách nào ngắn để làm những gì chúng ta muốn ...

Ngoại trừ ánh xạ None:

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

Thật không may (hay đúng hơn là may mắn cho tất cả các mục đích không phải là golf), điều này chỉ hoạt động trong Python 2.

Đối với nv:

  • nhoạt động như một chồng, đếm 1 - <number of unmatched '(' remaining>. Đối với mỗi (chúng tôi thấy, chúng tôi trừ đi 1 và cho mỗi lần )chúng tôi thấy chúng tôi thêm 1. Do đó, n >= 2tại bất kỳ thời điểm nào, chúng tôi đã thấy quá nhiều )s và chương trình không hợp lệ. Nếu nkhông kết thúc vào 1, thì chúng ta có ít nhất một cái (còn lại chưa từng có .
  • vkiểm tra tính hợp lệ và bắt đầu từ 1. Nếu chương trình không bao giờ không hợp lệ ( n >= 2hoặc A+B >= 2), sau đó vtrở thành 0 để đánh dấu sự vô hiệu.

Do đó, nếu chương trình hợp lệ, thì cuối cùng chúng ta phải có n = 1, v = 1. Nếu chương trình không hợp lệ, thì cuối cùng chúng ta phải có v = 0hoặc v = 1, n <= 0. Do đó tính hợp lệ có thể được thể hiện ngắn gọn như n*v>0.

(Cảm ơn @feersum vì vô số lời đề nghị hay đã mất 14 byte!)

Trước đây, trình dễ đọc hơn:

def F(p):
 p=map(None,*p.split("\n"));v=n=0
 for r in p:R=r.count;A=R("(");B=R(")");n+=A-B;v|=A+B>1or n<0
 return n<1>v

Đó là một cách sử dụng điên rồ của map...
xnor 3/03/2015

1
119 -> 106def F(p): v=n=3 for r in map(None,*p.split("\n")):A,B=map(R.count,"()");n+=A-B;v*=n>2>A+B return n*v==9
facerum 3/03/2015

@feersum Cảm ơn! Tôi đã cố gắng thay đổi orchuỗi thành so sánh, nhưng tôi không nghĩ sẽ thay đổi |=thành *=. Tuy nhiên, đã lấy đi một byte khác, bằng cách khiến mọi thứ trở nên lạc hậu hơn :)
Sp3000 3/03/2015

2

J, 64 byte

Đầu vào là một chuỗi với một dòng mới. Đầu ra là 0 hoặc 1.

(0=(1<|s)s+[:(|@{:+(0>])s)[:+/\]s=.+/@:)@(1 _1 0{~[:'()'&i.];.2)

Ví dụ sử dụng

   ]in=.'#(#)##',LF,'###',LF,'###(#)',LF
#(#)##
###
###(#)

   ((0=(1<|s)s+[:(|@{:+(0>])s)[:+/\]s=.+/@:)@(1 _1 0{~[:'()'&i.];.2)) in
0

Phương pháp như sau

  • cắt đầu vào tại dòng mới và đưa vào một ma trận ];.2
  • bản đồ (/ )/ anything elsethành 1/ -1/0 1 _1 0{~[:'()'&i.]
  • định nghĩa một s=.+/@:trạng từ được thêm vào một động từ tính tổng đầu ra của động từ
  • thêm giá trị trong cột ]s

    • kiểm tra ()số dư dương trong mọi tiền tố [:(0>])s)[:+/\]
    • kiểm tra ()số dư bằng nhau trong toàn bộ danh sách (nghĩa là trong tiền tố cuối cùng) |@{:@]
  • thêm abs (giá trị) vào cột và kiểm tra mọi phần tử để có giá trị tối đa là 1 (1<|s)s

  • vì tất cả các kiểm tra trước đó đều mang lại kết quả dương tính khi thất bại, chúng tôi cộng chúng lại và so sánh với 0 để có được tính hợp lệ của đầu vào 0=]


2

J, 56 byte

3 :'*/0<: ::0:(+/\*:b),-.|b=.+/+.^:_1]0|:''()''=/];.2 y'

Đó là một hàm ẩn danh chấp nhận một chuỗi có dòng mới và trả về 0 hoặc 1. Đọc từ phải sang trái:

  • ];.2 y, như trong đệ trình J khác, cắt chuỗi yở tất cả các lần xuất hiện của ký tự cuối cùng của nó (đó là lý do tại sao đầu vào cần một dòng mới ở cuối) và tạo một ma trận hình chữ nhật có các hàng là các mảnh, được đệm bằng khoảng trắng nếu cần.

  • '()'=/so sánh mọi ký tự trong ma trận đó trước (và sau đó )trả về một danh sách hai ma trận 0-1.

  • +.^:_1]0|:biến danh sách hai ma trận thành một ma trận gồm các số phức. Cho đến nay, chương trình biến mọi (đầu vào thành 1, mọi )thành i và mọi ký tự khác thành 0.

  • b=.+/gán tổng các hàng của ma trận phức đó cho b.

  • -.|blập danh sách 1- | z | cho mọi z trong b. Điều kiện mà mỗi cột chứa tối đa một dấu ngoặc đơn dịch cho tất cả các số 1- | z | là không âm.

  • +/\*:blà vectơ của tổng chạy của bình phương của các số trong b. Nếu mỗi cột chứa tối đa một dấu ngoặc đơn thì bình phương của các số trong btất cả là 0, 1 hoặc -1. Kết ,hợp vectơ này với vectơ 1- | z | 's.

  • bây giờ tất cả những gì chúng ta cần làm là kiểm tra xem các mục trong vectơ nối của chúng ta vcó phải là số thực không âm, điều này gần như */0<:v, ngoại trừ việc gây ra lỗi nếu một số mục vkhông có thực, vì vậy chúng ta thay thế <:bằng <: ::0:0 chỉ trong trường hợp có lỗi .


Những ý tưởng tuyệt vời với những con số phức tạp nhưng bạn cũng cần kiểm tra xem 0={:+/\*:bvì ví dụ như (không hợp lệ.
Randomra

Ồ, bạn nói đúng, @randomra, tôi quên mất!
Omar

1
0=(-|)vngắn hơn 2 byte để kiểm tra các số thực không âm. (Chúng ta hãy đánh bại CJam !: P)
Randomra

1
Oh, và invthay vì ^:_1 lưu một byte khác.
Randomra

1
Quay lại 56 (với kiểm tra số dư) : 3 :'*/0=({:,]-|)(-.@|,+/\@:*:)+/+.inv]0|:''()''=/];.2 y'.
Randomra
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.