Un vérificateur de syntaxe basique de type Pyth

25

Pyth est un langage de golf basé sur Python. Il utilise la notation de préfixe, chaque commande ayant une arité différente (nombre d'arguments qu'elle accepte).

Votre tâche consiste à écrire un vérificateur de syntaxe pour un langage de type Pyth (inexistant), Pith.

Syntaxe de Pith

Pith n'a que 8 commandes à caractère unique:

01234()"

01234chacun a une arité du nombre correspondant, et donc s'attend à ce que de nombreux arguments après. Par exemple,

400010

est un programme Pith correct car il 4est suivi de quatre arguments 0 0 0et 10le dernier est 1suivi d'un seul argument 0. Pour visualiser cela, nous pouvons regarder l'arborescence suivante:

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

Rest le nœud racine. Une autre façon de penser à cela est que chaque nombre fait référence au nombre d'enfants que le nœud correspondant a dans l'arbre ci-dessus.

Voici un autre programme Pith valide, avec plus d'une commande de base:

210010

correspond à

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

D'autre part,

3120102100

n'est pas un programme Pith correct car l'initiale 3n'a que deux arguments, que nous pouvons voir en regardant l'arbre ci-dessous:

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

(Commence ensuite une illimitée, et) se termine un illimité. Un illimité prend n'importe quel nombre d'arguments (avec avidité) et compte comme un seul argument pour toute commande parent. Toutes les bornes non encore ouvertes à la fin du programme sont automatiquement fermées. Une )commande n'est pas une erreur si aucune limite n'est ouverte - elle ne fait rien. *

Par exemple, le programme Pith

)31(0)0(201000100

correspond à l'arbre

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

Les limites non vides sont correctes, tout ()comme un programme Pith valide.

Un programme Pith non valide avec un illimité est

12(010

puisque le 2seul reçoit un argument (le sans limite).

Enfin, "démarre et termine une chaîne, qui est toujours de 0 arité et compte comme un seul argument, par exemple

2"010""44)()4"

qui est juste un 2être passé deux arguments de chaîne"010" et "44)()4". Comme les chaînes non liées, les chaînes peuvent également être vides et toutes les chaînes non fermées à la fin du programme sont automatiquement fermées.

* Cette partie est différente de la Pyth originale qui en fait fait faire quelque chose dans un cas comme1) , mettant fin à la 1-arité et d' élever une erreur.

Entrée sortie

L'entrée sera une seule chaîne non vide composée uniquement des caractères 01234()" . Vous pouvez éventuellement supposer qu'une nouvelle ligne de fin supplémentaire est toujours présente. Vous pouvez écrire une fonction ou un programme complet pour ce défi.

Vous devez sortir une valeur véridique si l'entrée est Pith syntaxiquement valide, ou une valeur fausse sinon. Les valeurs de vérité et de fausse doivent être fixes, vous ne pouvez donc pas sortir 1pour un programme valide et2 pour un autre.

Notation

C'est du code-golf, donc le code dans le moins d'octets gagne.

Cas de test

Vérité:

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

Faux:

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(""))
Sp3000
la source
L'arbre pour 20100100 (dans le premier exemple non borné) ne devrait-il pas l'être [( [2 [0] [1 [0] ] ] [0] [1 [0]] [0] ]? Celui que vous avez a des branches de 2, 0, 0, 1 et 0 - le second ne devrait pas être là.
bcsb1001
@ bcsb1001 Merci et corrigé. Je voulais montrer que les limites peuvent aller au-dessus de 4.
Sp3000
@Ypnypn il y a des cas de test disant qu'il est valide d'avoir plusieurs racines
Optimizer
Pourriez-vous s'il vous plaît ajouter le cas de test pour ())2)1))0"3())"))(ce qui devrait être vrai, je pense).
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Ajouté - c'est en effet vrai (car c'est essentiellement ()210""avec beaucoup de non-opérations)
Sp3000

Réponses:

12

CJam, 65 octets

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

Gosh, je souhaite que CJam ait Regex, cela aurait pu être terminé en moins de 50 octets puis

L'idée principale est de continuer à réduire les choses à 0c'est- 10à- dire à 0, 200à 0et ainsi de suite. Une fois cela fait, nous réduisons tous les crochets correspondants à 0, c'est- ()à- dire à 0, (0)à 0, (00)à 0et ainsi de suite. Nous répétons les Ltemps de cycle , où Lest la longueur d'entrée.

La chaîne d'entrée passe initialement par un traitement supplémentaire où nous ajustons pour inégalé "et ajoutons beaucoup de )pour compenser pour inégalé(

Cela garantit qu'après toutes les itérations, il ne reste plus 0(et pas d'opération )) dans la chaîne.

Mise à jour - correction d'un bug où le )non-fonctionnement de niveau supérieur était considéré comme dangereux

Expansion du code

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

Essayez-le en ligne ici ou exécutez toute la suite

Optimiseur
la source
11

Regex, saveur PCRE, 83 octets

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

Essayez-le ici.

Regex, saveur PCRE, 85 octets

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

Essayez-le ici.

Utilisé quelques idées dans la réponse de ce dan1111 .

Quelques explications sur(?2)*(()(?1))? .

jimmy23013
la source
(?2)*(()(?1))?est la dernière pièce du puzzle que je cherchais. Belle trouvaille! ;)
Martin Ender
Si je comprends bien la (?2)*(()(?1))?partie, la (()(?1))?partie ne correspond à rien, car elle (?2)*mange déjà tout ce qui (()(?1))?peut correspondre, et cette construction est utilisée pour définir le groupe de capture 3 lorsque nous entrons (et désactiver le groupe de capture 3 lorsque nous sommes en dehors de la ()construction (pour permettre la correspondance non apparié )).
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
4

lex, 182 octets (157 w / pile de taille fixe)

Ces programmes nécessitent que l'entrée soit une seule chaîne terminée par une nouvelle ligne de caractères valides.

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

Le programme ci-dessus sera défectueux s'il manque de mémoire, ce qui pourrait théoriquement se produire si vous lui en donnez assez (. Mais comme un défaut de segmentation est considéré comme un échec, je le prends pour "falsey", bien que la description du problème ne dise pas quoi faire si les ressources ne suffisent pas.

Je l'ai réduit de 157 octets en utilisant simplement une pile de taille fixe, mais cela semblait être de la triche.

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

Compiler:

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

Tester:

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

Sortie de test:

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
rici
la source
Je suppose que j'aurais dû être un peu plus clair - vous pouvez supposer que la nouvelle ligne n'est jamais là ou qu'elle est toujours là. Est ce que ça aide?
2015 à 15h34
Serait-il possible d'utiliser le programme de pile de taille fixe, mais de régler la taille de la pile sur la longueur de l'entrée?
isaacg
@isaacg Puisque l'entrée est stdin, nous n'avons aucune idée jusqu'à ce qu'elle soit lue. J'aurais pu facilement écrire un pilote qui utilise un argument ou une chaîne de ligne de commande, mais le golf a d'autres priorités. La pile dynamique en 25 caractères n'est pas mauvaise selon les normes c, mais je suis sûr qu'elle peut toujours être jouée.
rici
4

80386 Assembleur, 97 octets

Vidage hexadécimal:

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                                       .

Cela parcourt l'entrée une fois, poussant des nombres supérieurs à zéro sur la pile et les décrémentant lorsqu'un zéro est traité. Les éléments non liés sont traités comme -1.

Prototype de fonction (en C) (la fonction retourne 0 si invalide et 1 si valide):

int __cdecl test(char *in);

Assemblage équivalent (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

Le code suivant en C peut être utilisé avec GCC sur un système POSIX pour tester:

#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;
}
es1024
la source
3

Python 2, 353 octets

La fonction d'analyse parcourt les jetons un par un et construit un arbre de la structure du programme. Les programmes non valides déclenchent une exception qui entraîne l'impression d'un zéro (Falsy), sinon une analyse réussie entraîne un un.

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

La sortie des tests montrant la sortie de l'analyseur:

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

Le code avant le minifieur:

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
Logic Knight
la source
Belle (ab) utilisation des exceptions! Vous pouvez économiser certains espaces en échangeant l'ordre des opérandes ==dans les tests - mettre les chaînes en premier signifie que vous pouvez le faire if')'==q. Je crois que l'une des breakdéclarations pourrait être remplacée par f=0, car cela vous permettra également de sortir de la while fboucle. Enfin, au lieu de assert x==yvous pouvez utiliser 1/(x==y)pour un ZeroDivisionError. ;)
DLosc
@DLosc, merci pour quelques conseils de golf très utiles. Si j'étais parmi les leaders de la compétition de golf, j'utiliserais vos idées pour concourir. Comme mon entrée est loin d'être compétitive (au niveau du golf), je préfère la laisser comme un exemple principalement lisible. J'ai cependant noté vos techniques intelligentes pour une utilisation future ;-)
Logic Knight
1

Pip , 88 72 octets

Idée tirée du CJam d' Optimizer . Mon coup initial au problème avec un analyseur de descente récursif était ... plutôt plus long.

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

Formaté, avec explication:

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

Astuces intéressantes:

  • De nombreux opérateurs travaillent par élément sur les listes et les plages. Ainsi 0X,5, par exemple, est 0 X [0 1 2 3 4] == ["" "0" "00" "000" "0000"].
  • Il y a quelques jours, l' Ropérateur ternaire eplace peut prendre une liste pour n'importe lequel de ses arguments: "abracadabra" R ["br" "ca"] 'bdonne ababdaba, par exemple. Je fais bon usage de cette fonctionnalité zici.
  • Les valeurs de fausseté dans Pip incluent la chaîne ""vide, la liste vide []et tout scalaire qui est zéro. Ainsi, 0est faux, mais aussi 0.0et "0000000". Cette fonctionnalité est parfois gênante (pour tester si une chaîne est vide, il faut tester sa longueur car elle "0"est fausse aussi), mais pour ce problème c'est parfait.
DLosc
la source
1

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

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,""))
SuperJedi224
la source