Trình kiểm tra cú pháp cơ bản giống như Pyth


25

Pyth là một ngôn ngữ chơi gôn dựa trên Python. Nó sử dụng ký hiệu tiền tố, với mỗi lệnh có một mức độ khác nhau (số lượng đối số mà nó chấp nhận).

Nhiệm vụ của bạn là viết một trình kiểm tra cú pháp cho một ngôn ngữ giống như Pyth (không tồn tại), Pith.

Cú pháp của Pith

Pith chỉ có 8 lệnh char đơn:

01234()"

01234mỗi cái có số lượng tương ứng, và do đó mong đợi có nhiều đối số sau nó. Ví dụ,

400010

là một chương trình Pith chính xác vì 4được theo sau bởi bốn đối số 0 0 010cuối cùng là 1đối số tiếp theo là đối số duy nhất 0. Để hình dung điều này, chúng ta có thể nhìn vào cây sau:

      R
      |
      4
      |
-------------
|   |   |   |
0   0   0   1
            |
            0

nơi Rlà nút gốc. Một cách khác để suy nghĩ về điều này là mỗi số đề cập đến số lượng con mà nút tương ứng có trong cây ở trên.

Đây là một chương trình Pith hợp lệ khác, với nhiều hơn một lệnh cơ sở:

210010

tương ứng với

           R
           |
     -------------
     |           |
     2           1
     |           |
 ---------       0
 |       |
 1       0
 |
 0

Mặt khác,

3120102100

không một chương trình phần cốt lõi đúng bởi vì ban đầu 3chỉ có hai đối số, mà chúng ta có thể nhìn thấy bằng cách nhìn vào cây dưới đây:

                R
                |
                3
                |
     ------------------------ ??
     |          |
     1          2
     |          |
     2        ------
     |        |    |
   ------     1    0
   |    |     |
   0    1     0
        |
        0

Tiếp theo (bắt đầu một không giới hạn, và )kết thúc một không giới hạn. Một liên kết không có bất kỳ số lượng đối số (tham lam) và được tính là một đối số duy nhất cho bất kỳ lệnh cha. Bất kỳ liên kết nào vẫn mở vào cuối chương trình sẽ tự động đóng lại. Một )lệnh không phải là một lỗi nếu không unboundeds được mở - nó chỉ không có gì *.

Chẳng hạn, chương trình Pith

)31(0)0(201000100

tương ứng với cây

            R
            |
            3
            |
    ------------------------------
    |       |                    |
    1       0                    (
    |                            |
    (              -----------------------------
    |              |      |      |      |      |
    0              2      0      0      1      0
                   |                    |
                -------                 0
                |     |
                0     1
                      |
                      0

Không có liên kết trống là được, vì vậy ()một chương trình Pith hợp lệ.

Một chương trình Pith không hợp lệ với không giới hạn là

12(010

2chỉ nhận được một đối số (không giới hạn).

Cuối cùng, "bắt đầu và kết thúc một chuỗi, luôn là 0 arity và được tính là một đối số duy nhất, ví dụ:

2"010""44)()4"

mà chỉ là một 2thông qua hai đối số chuỗi "010""44)()4". Giống như không liên kết, các chuỗi cũng có thể trống và bất kỳ chuỗi nào không được tiết lộ vào cuối chương trình sẽ tự động bị đóng.

* Phần này là khác nhau từ Pyth gốc mà thực sự không làm điều gì đó trong một trường hợp như thế 1), kết thúc 1-arity và nâng cao một lỗi.

Đầu ra đầu vào

Đầu vào sẽ là một chuỗi không trống duy nhất chỉ bao gồm các ký tự 01234()". Bạn có thể tùy ý cho rằng một dòng mới bổ sung luôn luôn có mặt. Bạn có thể viết một chức năng hoặc một chương trình đầy đủ cho thử thách này.

Bạn nên xuất một giá trị trung thực nếu đầu vào có giá trị cú pháp Pith hoặc giá trị giả mạo khác. Các giá trị trung thực và sai lệch phải được cố định, vì vậy bạn không thể xuất ra 1một chương trình hợp lệ và 2cho một chương trình khác.

Chấm điểm

Đây là mã golf, vì vậy mã trong ít byte nhất sẽ thắng.

Các trường hợp thử nghiệm

Sự thật:

0
)
(
"
()
""
10
400010
210010
("")00
3"""""
(0)))0)1)0
2(2(2(0)0)0)0
2"010""44)()4"
)31(0)0(201000100
())2)1))0"3())"))
3("4321("301(0)21100"4")"123"00)40"121"31000""01010

Giả mạo:

1
1(310
(1)0)
12(010
4"00010"
3120102100
20(2((0)(0)))
2(2(2(0)0)0)01)
4(0102)00)00000
2"00"("00"2(""))

Không phải cây cho năm 20100100 (trong ví dụ không giới hạn đầu tiên) phải [( [2 [0] [1 [0] ] ] [0] [1 [0]] [0] ]không? Cái bạn có có các nhánh 2, 0, 0, 1 và 0 - cái thứ hai không nên có.
bcsb1001 15/03/2015

@ bcsb1001 Cảm ơn và sửa chữa. Tôi muốn chứng minh rằng những người không liên kết có thể vượt lên trên 4.
Sp3000 15/03/2015

@Ypnypn có các trường hợp thử nghiệm nói rằng nó hợp lệ để có nhiều gốc
Trình tối ưu hóa

Bạn có vui lòng thêm trường hợp thử nghiệm cho ())2)1))0"3())"))(điều này đúng không, tôi nghĩ vậy).
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Đã thêm - điều đó thực sự đúng (vì về cơ bản nó ()210""có rất nhiều hoạt động không hoạt động)
Sp3000

Câu trả lời:


12

CJam, 65 byte

q'"/La+2%{0s*}:Z~_,:L')*+{L{4{)_Z+s/Z}/L{'(\Z')++/Z}/}*')-}2*0s-!

Trời ạ, tôi ước rằng CJam có Regex, điều này có thể đã được hoàn thành trong ít hơn 50 byte sau đó

Ý tưởng chính là để giữ cho việc giảm công cụ để 0ví dụ 10để 0, 200đến 0và vân vân. Khi đã xong, chúng tôi giảm tất cả dấu ngoặc phù hợp với 0, tức là ()đến 0, (0)đến 0, (00)đến 0và vân vân. Chúng tôi lặp lại Lthời gian chu kỳ , trong đó Llà chiều dài đầu vào.

Chuỗi đầu vào ban đầu trải qua quá trình xử lý bổ sung, trong đó chúng tôi điều chỉnh cho chưa từng có "và thêm rất nhiều )để bù cho chưa từng có(

Điều này đảm bảo rằng sau tất cả các lần lặp, chúng ta chỉ nên có 0(và không có op )) trong chuỗi.

Cập nhật - đã sửa một lỗi trong đó )no-op cấp cao nhất được coi là có hại

Mở rộng mã

q'"/La+2%{0s*}:Z~_,:L')*      "Part 1 - Preprocessing";
q'"/                          "Read the input and split it on quote";
    La+                       "Add an extra empty array to the split array to compensate";
                              "for unmatched ending quote";
        2%                    "Take every other splitted part, ignoring the contents";
                              "of the strings in the code";
          {0s*}:Z~            "Join the parts by string 0. Also create a function Z";
                              "that does that for future use. We are now done with";
                              "reducing "XYZ" to 0 ";
                  _,:L        "Store the length of the remaining code in L";
                      ')*     "Append L ) to the string to compensate for unmatched (";

{L{4{)_Z+s/Z}/L{'(\Z')++/Z}/}*')-}2*   "Part 2 - the reducing loop";
 L{                         }*         "Run the reduction logic L times";
   4{)_Z+s/Z}/                         "Part 2a - reducing arities";
   4{       }/                         "Run the iteration for 0, 1, 2 and 3";
     )_                                "Increment the iteration number and make a copy";
       Z+s                             "Get that many 0 and append it to the number";
          /Z                           "Split the code onto this number and convert it";
                                       "to 0. This successfully reduces 10, 200, ";
                                       "3000 and 4000 to 0";
              L{'(\Z')++/Z}/           "Part 2b - reducing groups";
              L{          }/           "Run the iteration for 0 through L - 1";
                '(\Z')++               "Get the string '(<iteration number of 0>)'";
                        /Z             "split on it and join by 0. This successfully";
                                       "reduces (), (0), (00) and so on .. to 0";
                              ')-      "After running the part 2 loop L times, all";
                                       "reducible arities and brackets should be reduced";
                                       "except for cases like '30)00' where the no-op )";
                                       "breaks the flow. So we remove ) from the code";
                                       "and run Part 2 L times again";

0s-!                          "Now, if the code was valid, we should only have 0 in the";
                              "remaining code. If not, the code was invalid";

Dùng thử trực tuyến tại đây hoặc chạy toàn bộ bộ


11

Regex, hương vị PCRE, 83 byte

^(?3)*\)*$(()((?(2)|\)*)(\((?1)*(\)|$)|0|"[^"]*.?|(1|(2|(3|4(?3))(?3))(?3))(?3))))?

Hãy thử nó ở đây.

Regex, hương vị PCRE, 85 byte

^((?(3)|\)*)(?>\((?2)*(()(?1))?(\)|$)|0|"[^"]*.?|(1|(2|(3|4(?1))(?1))(?1))(?1)))*\)*$

Hãy thử nó ở đây.

Đã sử dụng một số ý tưởng trong câu trả lời của dan1111 này .

Một số giải thích về(?2)*(()(?1))? .


(?2)*(()(?1))?là mảnh ghép cuối cùng tôi đang tìm kiếm. Đẹp tìm thấy! ;)
Martin Ender

Nếu tôi hiểu (?2)*(()(?1))?chính xác phần đó, (()(?1))?phần đó không bao giờ khớp với bất cứ thứ gì, vì (?2)*đã ăn hết mọi thứ (()(?1))?có thể khớp và cấu trúc này được sử dụng để đặt bắt nhóm 3 khi chúng ta nhập (và hủy đặt nhóm 3 khi chúng ta ở ngoài ()cấu trúc (để cho phép khớp không ghép đôi )).
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

4

lex, 182 byte (157 w / ngăn xếp kích thước cố định)

Các chương trình này yêu cầu đầu vào là một chuỗi ký tự hợp lệ mới kết thúc.

%%
 int n=0,s=0,*t=0;
[0-4] n+=*yytext-48-!!n;
\( (t=realloc(t,(s+1)*sizeof n))[s++]=n-!!n;n=0;
\) if(s&&n)exit(1);s&&(n=t[--s]);
\"[^"]*.? n-=!!n;
\n while(s)t[--s]&&n++;exit(!!n);

Chương trình trên sẽ segfault nếu hết bộ nhớ, về mặt lý thuyết có thể xảy ra nếu bạn cung cấp đủ (. Nhưng vì một segfault được coi là thất bại, tôi coi đó là "falsey", mặc dù mô tả vấn đề không nói phải làm gì nếu tài nguyên không đủ.

Tôi đã cắt nó xuống 157 byte chỉ bằng cách sử dụng ngăn xếp có kích thước cố định, nhưng điều đó có vẻ như gian lận.

%%
 int n=0,s=0,t[9999];
[0-4] n+=*yytext-48-!!n;
\( t[s++]=n-!!n;n=0;
\) if(s&&n)exit(1);s&&(n=t[--s]);
\"[^"]*.? n-=!!n;
\n while(s)t[--s]&&n++;exit(!!n);

Để biên dịch:

flex -o pith.c pith.l    # pith.l is the above file
c99 -o pith pith.c -lfl

Kiểm tra:

while IFS= read -r test; do
  printf %-78s "$test"
  if ./pith <<<"$test"; then echo "OK"; else echo "NO"; fi
done <<EOT
0
)
(
"
()
""
10
400010
210010
("")00
3"""""
2(2(2(0)0)0)0
2"010""44)()4"
)31(0)0(201000100
3("4321("301(0)21100"4")"123"00)40"121"31000""01010
1
1(310
12(010
4"00010"
3120102100
20(2((0)(0)))
2(2(2(0)0)0)01)
4(0102)00)00000
2"00"("00"2(""))
EOT

Đầu ra thử nghiệm:

0                                                                             OK
)                                                                             OK
(                                                                             OK
"                                                                             OK
()                                                                            OK
""                                                                            OK
10                                                                            OK
400010                                                                        OK
210010                                                                        OK
("")00                                                                        OK
3"""""                                                                        OK
2(2(2(0)0)0)0                                                                 OK
2"010""44)()4"                                                                OK
)31(0)0(201000100                                                             OK
3("4321("301(0)21100"4")"123"00)40"121"31000""01010                           OK
1                                                                             NO
1(310                                                                         NO
12(010                                                                        NO
4"00010"                                                                      NO
3120102100                                                                    NO
20(2((0)(0)))                                                                 NO
2(2(2(0)0)0)01)                                                               NO
4(0102)00)00000                                                               NO
2"00"("00"2(""))                                                              NO

Tôi đoán tôi nên đã rõ ràng hơn một chút - bạn có thể cho rằng một trong những dòng mới không bao giờ ở đó, hoặc luôn luôn ở đó. cái đó có giúp ích không?
Sp3000

Có thể sử dụng chương trình ngăn xếp kích thước cố định, nhưng để đặt kích thước của ngăn xếp theo chiều dài của đầu vào?
isaacg

@isaacg Vì đầu vào là stdin, chúng tôi không có ý tưởng nào cho đến khi nó được đọc. Tôi có thể dễ dàng viết một trình điều khiển sử dụng một dòng lệnh arg hoặc chuỗi nhưng golf có các ưu tiên khác. Ngăn xếp động trong 25 ký tự không tệ theo tiêu chuẩn c, nhưng tôi chắc chắn rằng nó vẫn có thể được chơi gôn.
rici

4

Trình biên dịch 80386, 97 byte

Đổ lục giác:

0000000: 8b54 2404 5589 e531 c96a ff8a 022c 303c  .T$.U..1.j...,0<
0000010: f275 04f6 d530 c084 ed75 263c f875 0141  .u...0...u&<.u.A
0000020: 3cf9 750f 84c9 7419 4958 3c00 7c03 50eb  <.u...t.IX<.|.P.
0000030: 2430 c084 c075 0958 483c ff7f 0140 ebf3  $0...u.XH<...@..
0000040: 5042 8a02 84c0 75c5 4a84 edb0 2275 be84  PB....u.J..."u..
0000050: c9b0 2975 b85a 31c0 39e5 7501 4089 ec5d  ..)u.Z1.9.u.@..]
0000060: c3                                       .

Điều này chạy qua đầu vào một lần, đẩy các số lớn hơn 0 lên ngăn xếp và giảm chúng khi số 0 được xử lý. Không giới hạn được xử lý như -1.

Nguyên mẫu hàm (tính bằng C) (hàm trả về 0 nếu không hợp lệ và 1 nếu hợp lệ):

int __cdecl test(char *in);

Lắp ráp tương đương (NASM):

bits 32
; get input pointer into edx
mov edx, [esp+4]                ; 8B 54 24 04

; save ebp; set ebp = esp
push ebp                        ; 55
mov ebp, esp                    ; 89 E5

; clear ecx
xor ecx, ecx                    ; 31 C9

; push base -1
push byte(-1)                   ; 6A FF

; get top char
mov al, [edx]                   ; 8A 02

    sub al, 0x30                ; 2C 30

    ; if al == quote
    cmp al, 0xF2                ; 3C F2
    jne $+6                     ; 75 04
        ; set ch (in quote?) to opposite
        not ch                  ; F6 D5
        ; set value to 0
        xor al, al              ; 30 C0

    ; if in quote, continue
    test ch, ch                 ; 84 ED
    jnz $+40                    ; 75 26

    cmp al, 0xF8                ; 3C F8
    jne $+3                     ; 75 01
        ; increment cl=depth
        inc ecx                 ; 41

    cmp al, 0xF9                ; 3C F9
    jne $+17                    ; 75 0F
        ; check depth = 0
        test cl, cl             ; 84 C9
        jz $+27                 ; 74 19
        ; decrement cl=depth
        dec ecx                 ; 49
        ; pop and check -1
        pop eax                 ; 58
        cmp al, 0               ; 3C 00
        jl $+5                  ; 7C 03
            push eax            ; 50
            jmp $+38            ; EB 24
        xor al, al              ; 30 C0

    test al, al                 ; 84 C0
    jnz $+11                    ; 75 09
        pop eax                 ; 58
        dec eax                 ; 48
        cmp al, -1              ; 3C FF
        jg $+3                  ; 7F 01
            inc eax             ; 40
        jmp $-11                ; EB F3
    push eax                    ; 50

    inc edx                     ; 42
    mov al, [edx]               ; 8A 02
    test al, al                 ; 84 C0
    jnz $-57                    ; 75 C5

    dec edx                     ; 4A

    ; in quote?
    test ch, ch                 ; 84 ED
    mov al, 0x22                ; B0 22
    jnz $-64                    ; 75 BE

    ; depth not zero?
    test cl, cl                 ; 84 C9
    mov al, 0x29                ; B0 29
    jnz $-70                    ; 75 B8

; pop base -1
pop edx                         ; 5A

; set return value based on ebp/esp comparison
xor eax, eax                    ; 31 C0
cmp ebp, esp                    ; 39 E5
jne $+3                         ; 75 01
inc eax                         ; 40
; restore esp
mov esp, ebp                    ; 89 EC
; restore ebp
pop ebp                         ; 5D
; return
ret                             ; C3

Mã sau trong C có thể được sử dụng với GCC trên hệ thống POSIX để kiểm tra:

#include <sys/mman.h>
#include <stdio.h>
#include <string.h>

int main(){
    char code[] = {
        0x8b, 0x54, 0x24, 0x04, 0x55, 0x89, 0xe5, 0x31, 0xc9, 0x6a, 0xff,
        0x8a, 0x02, 0x2c, 0x30, 0x3c, 0xf2, 0x75, 0x04, 0xf6, 0xd5, 0x30, 
        0xc0, 0x84, 0xed, 0x75, 0x26, 0x3c, 0xf8, 0x75, 0x01, 0x41, 0x3c, 
        0xf9, 0x75, 0x0f, 0x84, 0xc9, 0x74, 0x19, 0x49, 0x58, 0x3c, 0x00, 
        0x7c, 0x03, 0x50, 0xeb, 0x24, 0x30, 0xc0, 0x84, 0xc0, 0x75, 0x09, 
        0x58, 0x48, 0x3c, 0xff, 0x7f, 0x01, 0x40, 0xeb, 0xf3, 0x50, 0x42, 
        0x8a, 0x02, 0x84, 0xc0, 0x75, 0xc5, 0x4a, 0x84, 0xed, 0xb0, 0x22, 
        0x75, 0xbe, 0x84, 0xc9, 0xb0, 0x29, 0x75, 0xb8, 0x5a, 0x31, 0xc0, 
        0x39, 0xe5, 0x75, 0x01, 0x40, 0x89, 0xec, 0x5d, 0xc3,
    };
    void *mem = mmap(0, sizeof(code), PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0);
    memcpy(mem, code, sizeof(code));
    int __cdecl (*test)(char *) = (int __cdecl (*)(char *)) mem;

    #define TRY(s) printf(s ": %d\n", test(s))

    printf("Truthy tests:\n");
    TRY("0");
    TRY(")");
    TRY("(");
    TRY("\"");
    TRY("()");
    TRY("\"\"");
    TRY("10");
    TRY("400010");
    TRY("210010");
    TRY("(\"\")00");
    TRY("3\"\"\"\"\"");
    TRY("(0)))0)1)0");
    TRY("2(2(2(0)0)0)0");
    TRY("2\"010\"\"44)()4\"");
    TRY(")31(0)0(201000100");
    TRY("())2)1))0\"3())\"))");
    TRY("3(\"4321(\"301(0)21100\"4\")\"123\"00)40\"121\"31000\"\"01010");

    printf("\nFalsy tests:\n");
    TRY("1");
    TRY("1(310");
    TRY("(1)0)");
    TRY("12(010");
    TRY("4\"00010\"");
    TRY("3120102100");
    TRY("20(2((0)(0)))");
    TRY("2(2(2(0)0)0)01)");
    TRY("4(0102)00)00000");
    TRY("2\"00\"(\"00\"2(\"\"))");

    munmap(mem, sizeof(code));
    return 0;
}

3

Python 2, 353 byte

Hàm phân tích từng bước thông qua các mã thông báo một lần và xây dựng một cây cấu trúc chương trình. Các chương trình không hợp lệ kích hoạt một ngoại lệ khiến cho số không (Falsy) được in, nếu không, việc phân tích cú pháp thành công sẽ dẫn đến một kết quả.

def h(f,k=0):
 b=[]
 if k:
  while f:b+=[h(f)]
  return b
 q=f.pop(0)
 if q==')':return[]
 elif q=='"':
  while f:
   q+=f.pop(0)
   if q[-1]=='"':break
 elif q=='(':
  while f:
   if f and f[0]==')':f.pop(0);break
   b+=h(f)
 else:
  for i in range(int(q)):b+=h(f)
  assert len(b)==int(q)
 return[[q,b]]
try:h(list(raw_input()));r=1
except:r=0
print r

Đầu ra của các thử nghiệm hiển thị đầu ra của trình phân tích cú pháp:

------------------------------------------------------------
True: 0
    0

------------------------------------------------------------
True: )

------------------------------------------------------------
True: (
    (

------------------------------------------------------------
True: "
    "

------------------------------------------------------------
True: ()
    (

------------------------------------------------------------
True: ""
    ""

------------------------------------------------------------
True: 10
    1
        0

------------------------------------------------------------
True: 400010
    4
        0
        0
        0
        1
            0

------------------------------------------------------------
True: 210010
    2
        1
            0
        0
    1
        0

------------------------------------------------------------
True: ("")00
    (
        ""
    0
    0

------------------------------------------------------------
True: 3"""""
    3
        ""
        ""
        "

------------------------------------------------------------
True: 2(2(2(0)0)0)0
    2
        (
            2
                (
                    2
                        (
                            0
                        0
                0
        0

------------------------------------------------------------
True: 2"010""44)()4"
    2
        "010"
        "44)()4"

------------------------------------------------------------
True: )31(0)0(201000100
    3
        1
            (
                0
        0
        (
            2
                0
                1
                    0
            0
            0
            1
                0
            0

------------------------------------------------------------
True: 3("4321("301(0)21100"4")"123"00)40"121"31000""01010
    3
        (
            "4321("
            3
                0
                1
                    (
                        0
                2
                    1
                        1
                            0
                    0
            "4"
        "123"
        0
    0
    4
        0
        "121"
        3
            1
                0
            0
            0
        ""
    0
    1
        0
    1
        0

------------------------------------------------------------
False: 1
0
------------------------------------------------------------
False: 1(310
0
------------------------------------------------------------
False: 12(010
0
------------------------------------------------------------
False: 4"00010"
0
------------------------------------------------------------
False: 3120102100
0
------------------------------------------------------------
False: 20(2((0)(0)))
0
------------------------------------------------------------
False: 2(2(2(0)0)0)01)
0
------------------------------------------------------------
False: 4(0102)00)00000
0
------------------------------------------------------------
False: 2"00"("00"2(""))
0

Mã trước khi khai thác:

def parse(tokens, first=False):
    toklist = []
    if first:
        while tokens :
            toklist += [parse(tokens)]
        return toklist
    tok = tokens.pop(0)
    if tok == ')' :
        return []
    elif tok == '"':
        while tokens:
            tok += tokens.pop(0)
            if tok[-1] == '"' :
                break
    elif tok == '(':
        while tokens:
            if tokens and tokens[0] == ')' :
                tokens.pop(0);
                break
            toklist += parse(tokens)
    else:
        for i in range(int(tok)) :
            toklist += parse(tokens)
        assert len(toklist) == int(tok)
    return [[tok, toklist]]

try :
    parse(list(raw_input()));
    r = 1
except :
    r = 0
print r

Nice (ab) sử dụng các ngoại lệ! Bạn có thể lưu một số khoảng trắng bằng cách hoán đổi thứ tự của toán hạng ==trong các bài kiểm tra - đặt các chuỗi đầu tiên có nghĩa là bạn có thể làm if')'==q. Tôi tin rằng một trong những breaktuyên bố có thể được thay thế bằng f=0, vì điều đó cũng sẽ giúp bạn thoát khỏi while fvòng lặp. Cuối cùng, thay vì assert x==ybạn có thể sử dụng 1/(x==y)cho a ZeroDivisionError. ;)
DLosc

@DLosc, cảm ơn vì một số mẹo chơi golf rất hữu ích. Nếu tôi nằm trong số những người dẫn đầu trong cuộc thi golf, tôi sẽ sử dụng ý tưởng của bạn để thi đấu. Vì mục nhập của tôi là xa cạnh tranh (khôn ngoan golf), tôi muốn để nó như một ví dụ dễ đọc nhất. Tôi đã lưu ý các kỹ thuật thông minh của bạn mặc dù để sử dụng trong tương lai ;-)
Logic Knight

1

Pip , 88 72 byte

Ý tưởng được lấy từ CJam Tối ưu hóa . Cú đâm ban đầu của tôi về vấn đề với trình phân tích cú pháp gốc đệ quy là ... khá lâu.

Qpz:,5.iX,5AL'(.0X,#p.')p^:'"Fj,#pIj%2p@j:0p:Jpp.:')X#pL#ppR:z0!pRM')Rz0

Được định dạng, với lời giải thích:

Qp                Query user for p
z:                Store the following list in z:
  ,5 . 0X,5         For x in range(5), concatenate x zeros to it
  AL                (append list)
  '(. 0X,#p .')     For x in range(len(p)), concatenate x zeros inside parens
p^: '"            Split p on " and assign result back to p
Fi,#p             Loop over the indices of the resulting list:
 Ii%2               If index is odd:
  p@i:0               Replace that item with 0
p: Jp             Concatenate the results and assign back to p
p.: ')X#p         Append len(p) closing parens to p
L#p               Loop len(p) times:
 pR:z0              Replace every occurrence in p of items of z with 0
! pRM')Rz0        Remove ) from result and replace z with 0 one more time; then
                  take logical negation, which will be true iff string is empty OR
                  consists only of zeros

Thủ thuật thú vị:

  • Nhiều nhà khai thác làm việc theo mục trên danh sách và phạm vi. Vì vậy 0X,5, ví dụ, là0 X [0 1 2 3 4] == ["" "0" "00" "000" "0000"] .
  • Kể từ một vài ngày trước, ternary Rnhà điều hành eplace có thể mất một danh sách cho bất kỳ đối số của nó: "abracadabra" R ["br" "ca"] 'bcho phép ababdaba, ví dụ. Tôi sử dụng tốt tính năng này với zở đây.
  • Các giá trị giả trong Pip bao gồm chuỗi ""rỗng [], danh sách trống và bất kỳ vô hướng nào bằng không. Như vậy, 0là sai, nhưng cũng 0.0"0000000". Tính năng này đôi khi không thuận tiện (để kiểm tra xem một chuỗi có trống không, người ta phải kiểm tra độ dài của nó vì "0"nó cũng sai), nhưng đối với vấn đề này thì nó hoàn hảo.

1

Javascript (ES6), 289 288 285 282 278 244 241 230 byte

c=prompt(k="0"),j=c[l="length"];if((c.match(/"/g)||[])[l]%2)c+='"';c=c[R="replace"](/".*?"/g,k);c+=")".repeat(j);while(j--)c=c[R](/\(0*\)/,k)[R](/10/g,k)[R](/200/g,k)[R](/3000/g,k)[R](/40000/g,k);alert(!c[R](/0/g,"")[R](/\)/g,""))
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.