S'agit-il d'un nom de variable valide?


23

Objectif

Écrivez un programme ou une fonction qui vérifie si un nom de variable est valide et affichez 1 ou Trues'il est valide, 0,5 s'il est valide mais commence par un trait de soulignement (_) et 0 ou Falses'il n'est pas valide.

Règles

  • Un nom de variable dans la plupart des langues est valide s'il commence par un trait de soulignement ou une lettre (az, AZ, _) et que les autres caractères sont des traits de soulignement, des lettres ou des chiffres. (az, AZ, 0-9, _)
  • Sortie 1 ou Truesi le nom de la variable est valide et 0 ou Falsesi non valide.
  • Cependant, il n'est pas recommandé de démarrer une variable avec un trait de soulignement, donc renvoyez 0,5 si elle commence par un trait de soulignement et que le nom est valide.

Cas de test

Contribution

abcdefghijklmnop

Sortie

1

Contribution

_test_

Sortie

0.5 (commence par un trait de soulignement)

Contribution

123abc

Sortie

0 (commence par un chiffre)

Contribution

A_b1C_23

Sortie

1

Contribution

_!

Sortie

0 (pas 0,5 car ce n'est pas valide)

Contribution

magical pony1

Sortie

0 (sans espaces)

Des échappatoires standard s'appliquent.

C'est le , donc le code le plus court l'emporte.

Bonus: -10% si votre programme / fonction sort 0pour une chaîne vide ( "").


1
Pouvons-nous produire du vrai / faux / quoi que ce soit?
CalculatorFeline

5
Il suffit de noter qu'en python, les scores inférieurs sont souvent utilisés. Les classes ont besoin d'une fonction init, les fonctions d'aide dans les classes sont parfois commencées par un trait de soulignement.
Rɪᴋᴇʀ

1
@EasterlyIrk méfiez-vous des mini-démarques; tu voulais dire __init__; aussi, non, les cours n'ont pas besoin d' un __init__mais en ont généralement un
cat

6
Pouvons-nous supposer que l'entrée ne sera pas vide? (La plupart des réponses actuelles semblent échouer pour une entrée vide.)
Dennis

1
Ce bonus est-il arrondi à la hausse ou à la baisse? Si c'est le cas, cela ne vaut vraiment pas la peine d'avoir l'ensemble de réponses actuel
Blue

Réponses:


13

JavaScript (ES6), 37 - 10% = 33,3 octets

4 octets enregistrés grâce à @ edc65

5,6 octets enregistrés grâce à @Mateon

s=>!/^\d|\W|^$/.test(s)/-~(s[0]=='_')

3
Êtes-vous absolument sûr que ce n'est pas perl?
seequ

8

05AB1E , 25 24 20 19 octets

Code:

¬D'_Qsa·+¹žj-""Q*2/

Explication:

¬                     # Push input and also push the first character.
 D                    # Duplicate the first character.
  '_Q                 # Check if it is equal to an underscore character.
     sa               # Swap and check the duplicate if it's an alphabetic character.
       ·              # Double the value.
        +             # Add both values up
         ¹            # Take the first input.
          žj-         # žj is short for [a-zA-Z0-9_]. This will be substracted from the
                        initial string. 
             ""Q      # Check if the string is empty.
                *     # Multiply this with the first value.
                 2/   # Halve it, resulting into 0.0, 0.5, or 1.0.

En bref, la formule de la chaîne sen pseudocode est:

((s[0] == '_' + s.isalpha() × 2) × (s.remove([a-zA-Z0-9_]) == "")) / 2

Essayez-le en ligne!

Utilise l' encodage CP-1252 .


6

PHP (50 à 10% = 45)

Merci à Schism pour le -2 :)

preg_match('/^[a-z_]\w*$/i',$s)?$s[0]=='_'?.5:1:0;

Ne pas rivaliser avec les réponses de golflang, mais j'ai pensé que j'essaierais quand même.

preg_match('/^[a-z_]\w*$/i', $s) # Matches every a-zA-Z0-9_ string that doesnt start with a number
?   $s[0] == '_'                   # Then, if it starts with an _
    ?   .5                         # give 0.5 points
    :   1                          # If it doesn't, give 1
:   0;                             # If it didn't match the regex, give 0

Quelque chose à noter est qu'en PHP, sans le /umodificateur, \wne sélectionne que les lettres ASCII. Dans certaines autres langues / versions Regex, ce modèle ne fonctionnera pas.

Edit : Je vois beaucoup de gens qui utilisent \ w et \ d dans leurs réponses, lorsqu'ils utilisent une langue qui comprend aussi des lettres et des chiffres non ASCII. Ce n'est PAS le casse-tête. Ils ont tort. (Je ne peux pas encore voter / commenter, désolé de devoir le dire de cette façon.)


Bienvenue dans Programming Puzzles et Code Golf Stack Exchange. C'est une excellente réponse; les défis de code-golf sont souvent dans les langues ainsi qu'entre eux. Je vous donne un +1 pour cette solution! Bien joué.
wizzwizz4

1
Vous pouvez raser deux personnages avec [a-z].../i.
Schism

@Schism Merci. Je ne sais pas comment j'ai réussi à oublier cela, généralement je suis bon dans ce genre de puzzles d'
expression régulière

1
À propos de votre montage: pouvez-vous être plus précis - quelles langues? En javascript, \dc'est exactement la même chose que [0-9]. \west exactement le même que [A-Za-z0-9_] developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/…
edc65

La page de codes que la langue utilise n'est pas pertinente; tant que l'expression régulière gère correctement ASCII, elle est valide. Toutes les réponses actuelles basées sur des expressions rationnelles fonctionnent, à ma connaissance. Vous n'essayez pas de faire correspondre un nom de variable dans votre langue; vous essayez plutôt de faire correspondre un nom de variable en fonction des règles du défi.
Mego

5

Rétine, 30 - 10% = 27 28 - 10% = 25,2 29 - 10% = 26,1 octets

Les deux versions sont éligibles au bonus, car elles gèrent correctement les entrées vides (sorties 0)

J'ai dû corriger un bogue causé par l'une des fonctionnalités de regex .NET, qui considère certains (lire autant) caractères Unicode comme des caractères "word". Heureusement, cela ne m'a coûté qu'un seul octet dans les deux versions. Il ne s'agissait que d'ajouter un modificateur pour rendre le comportement de correspondance des expressions rationnelles conforme aux normes ECMAScript. Plus à ce sujet ici .

Nouvelle version 28 29 octets, réalisée par @ MartinBüttner. Merci!

^ _
$ _¶_
Mme` ^ (?! \ D) \ w + $
2
0,5

Explication

Tout d'abord, nous vérifions si l'entrée commence par un trait de soulignement. Si c'est le cas, l'entrée est dupliquée, avec une nouvelle ligne entre les deux. Par exemple: _test_-> _test_\n_test_, où \nest la nouvelle ligne. Ensuite , nous essayons de correspondre à quelque chose, qui ne commence pas par un chiffre, mais il est suivi par un certain nombre de caractères « mot » ( a-z, A-Z, chiffres et tirets) sur chaque ligne . Notez que si l'entrée a commencé avec un trait de soulignement et a été remplacée par deux lignes, cela correspondra aux deux lignes. Ensuite, nous vérifions si nous avons eu 2 correspondances et les remplaçons par 0.5. Une ligne vide ou invalide donnera toujours 0 correspondances et les noms de variables valides produiront toujours 1 correspondance.


Ma propre version 30 31 octets

Ae` ^ \ d | \ W
^ _. *
0,5
^ \ D. *
1
^ $
0

Explication

Tous, nous vérifions d' abord si les mises en entrée avec un chiffre ou contient un caractère non-mot (autre chose que a-z, A-Z, chiffres et tirets). Si c'est le cas, il est rejeté, car il n'est pas valide. Ensuite, nous vérifions s'il commence par un trait de soulignement. Si c'est le cas, il est remplacé par 0.5. Ensuite , nous vérifions si elle commence par un caractère non-chiffres (à ce stade , le premier caractère est soit 0, a-zou A-Z. Seuls a-zet A-Zsont non-chiffres, évidemment). Si c'est le cas, il est remplacé par un 1. Ensuite, nous vérifions la chaîne vide et la remplaçons par 0.

Essayez-le en ligne!
Essayez-le en ligne! Ancienne version


Attends attends. Au ^\D.*stade, il peut commencer par un 0? C'est bizarre.
CalculatorFeline

@CatsAreFluffy Il peut, s'il a commencé par un _et a été remplacé par 0.5. Ensuite, il commence par un 0.
daavko

Cela donne incorrectement un 1 pour l'entrée Ψ.
AdmBorkBork

@TimmyD Intéressant. Je ne comprends pas pourquoi il le fait. Une vérification rapide indique qu'il \wcorrespond à des caractères non ASCII, ce qu'il ne devrait pas faire (j'ai essayé de le donner ƜƝƞƟƠet ᎳᎴᎵᎶᎷᎸᎹde le saisir). J'examinerai cela plus tard. La solution possible semble remplacer \wpar [a-zA-Z\d_].
daavko

3

MATL , 27 octets

1)95=2/8M3Y2m+G7M95h4Y2hmA*

Cela fonctionne dans la version actuelle (15.0.0) de la langue.

L'entrée est une chaîne avec des guillemets simples.

Essayez-le en ligne!

Explication

1)      % take input implicitly. Get its first element
95=     % true if it equals 95 (underscore)
2/      % divide by 2: gives 0.5 if underscore, 0 if not
8M      % push first element of input again
3Y2     % predefined literal: string with all letters
m       % true if it's a letter
+       % add. Gives 1 if letter, 0.5 if underscore
G       % push input again
7M      % push string with all letters again
95h     % concatenate underscore
4Y2h    % predefined literal: string with all digits. Concatenate
mA      % true if all input chars belong to that concatenated string
*       % multiply. Display implicitly

3

Pyke , 21 octets

(non compétitif, soustraction de chaîne ajoutée, diverses constantes de chaîne)

Qh~u{Q~J\_+-|!Qh\_qh/

Explication:

Qh~u{                 - Check first char isn't a digit
     Q~J\_+-          - Is the input alphanumeric + "_"
            |!        - Combine
              Qh\_q   - Is the first char an "_"
                   h/ - Combine

3

Python 3, 36 octets

lambda s:s.isidentifier()/-~(s[:1]=='_')

Le code est de 40 octets long et donne droit au bonus de -10% .

Notez que cela ne fonctionnera correctement que pour les pages de codes qui n'ont pas de lettres / chiffres non ASCII.



2

Gogh , 29 octets

÷"[^\W\d]\w*"g¦"_.*"g+÷2=0.5¿

Exécutez en utilisant:

$ ./gogh no '÷"[^\W\d]\w*"g¦"_.*"g+÷2=0.5¿' "_test"

Explication

                   “ Implicit input                               ”
÷                  “ Duplicate the TOS                            ”
"[^\W\d]\w*"g      “ Fully match the STOS against the TOS (regex) ”
¦                  “ Swap the STOS and TOS                        ”
"_.*"g             “ Fully match the STOS against the TOS (regex) ”
+                  “ Add the TOS to the STOS                      ”
÷                  “ Duplicate the TOS                            ”
2=                 “ Determine if the TOS is equal to 2           ”
0.5¿               “ Leave the correct output on the stack        ”
                   “ Implicit output                              ”

2

Perl, 21 octets

$_=!/\W|^\d//2**/^_/

Le score comprend +1 octet pour le -pcommutateur. Essayez-le sur Ideone .


auriez-vous pu, par exemple, -$_||$_=...expliquer la réponse vide? (en utilisant -parce que +c'est un noop en perl)
Ven

Non, c'est une erreur d'exécution. Mais même si cela fonctionnait, cela aggraverait mon score.
Dennis

Je n'ai fait que des tests minimalistes, alors je vais vous faire confiance. Juste que 10% de 21 octets ne sont pas beaucoup ..
Ven

2

Pyth, 19 octets

c!:z"\W|^\d"0h!xz\_

Essayez-le avec le compilateur Pyth .

Notez que cela ne fonctionnera correctement que pour les pages de codes qui n'ont pas de lettres / chiffres non ASCII.

Comment ça marche

c!:z"\W|^\d"0h!xz\_  (implicit) Save the input in z.

  :z        0        Test if z matches the following regex:
    "\W|^\d"           A non-word character or a digit at the beginning.
                     This returns True iff z is an invalid name.
 !                   Apply logical NOT to yield True iff z is a valid name.
               xz\_  Find the first index of the underscore in z.
                     This yields 0 iff z begins with an underscore.
             h!      Apply logical NOT and increment.
                     This yields 2 if z begins with an underscore, 1 otherwise.
c                    Divide the two results.

2

Facteur , 84 * 0,9 = 76,5

USE: regexp
[ R/ [_a-zA-Z]\w*/ R/ _.*/ [ matches? 1 0 ? ] bi-curry@ bi 0 = 1 2 ? / ]

S'exécute sur l'écouteur (repl), définit une citation (fonction anonyme) qui prend une chaîne et affiche {0 | 1/2 | 1 }.

Le définissant comme un mot, c'est 97 caractères:

USE: regexp
: v ( s -- n ) R/ [_a-zA-Z]\w*/ R/ _.*/ [ matches? 1 0 ? ] bi-curry@ bi 0 = 1 2 ? / ;

Comment ça marche:

R/ [_a-zA-Z]\w*/ R/ _.*/définit deux expressions régulières. bi-curry@applique partiellement la citation [ matches? 1 0 ? ]à chaque expression régulière, en laissant deux citations au curry sur la pile. biapplique chaque citation à la chaîne d'argument.

Chacune de ces (citations au curry) laisse un 1 ou un 0, selon qu'elles correspondent. Le premier correspond aux noms bien formés, le second aux noms commençant par un trait de soulignement.

0 = 1 2 ? / La dernière valeur est remplacée par 1 si elle était 0, ou par 2 si elle était 1. Ensuite, la première (1 ou 0, valide ou non) est divisée par la seconde (2 ou 1, commence par un soulignement ou non) .

C'est loooong! Tous les conseils pour rétrécir un peu plus appréciés ...

Et je déteste les regexps!

PS.

{ 0 } [ "" v ] unit-test
{ 0 } [ "" v ] unit-test
{ 0 } [ "1" v ] unit-test
{ 0 } [ "1var" v ] unit-test
{ 0 } [ "var$" v ] unit-test
{ 0 } [ "foo var" v ] unit-test
{ 1 } [ "v" v ] unit-test
{ 1 } [ "var" v ] unit-test
{ 1 } [ "var_i_able" v ] unit-test
{ 1 } [ "v4r14bl3" v ] unit-test
{ 1/2 } [ "_" v ] unit-test
{ 1/2 } [ "_v" v ] unit-test
{ 1/2 } [ "_var" v ] unit-test
{ 1/2 } [ "_var_i_able" v ] unit-test
{ 1/2 } [ "_v4r14bl3" v ] unit-test

tous les tests réussissent;)


Je me demande simplement si l'espace est vraiment nécessaire? Je ne peux pas le dire avec certitude car je ne connais pas la langue ou je n'ai pas d'interprète.
Mama Fun Roll

@MamaFunRoll ouais, pas la meilleure langue de golf! Dans la tradition du Forth, seuls les délimiteurs sont des caractères d'espacement.
fede s.

Oh je vois. Ici, ayez un vote positif.
Mama Fun Roll

Ouais, ty! Maintenant, pour briser les ravages avec mon commentaire partout-priv!
fede s.

2

Dyalog APL , 19 octets - 10% = 17,1

{(0≤⎕NC⍵)÷1+'_'=⊃⍵}

{... ... }fonction anonyme où l'argument droit est représenté par le
⊃⍵premier caractère (donne l' espace si vide)
'_'=1 si égal à « underbar, 0 sinon
1+évalue à 2 si underbar initiale, 1 autre
⎕NC⍵ nom de classe ; -1 si nom non valide, 0 si non défini (mais nom valide), 2-9 si défini (et donc valide)


1

Mathematica, 93 octets

If[#~StringMatchQ~RegularExpression@"[A-Za-z_][0-9A-Za-z_]*",If[#~StringTake~1=="_",.5,1],0]&

Honnêtement, je ne sais pas si cela peut être approfondi.


1

Perl, 34 + 1 = 35 octets

$_=/^([^\W\d])\w*$//(($1 eq"_")+1)

Utilise le -pdrapeau.

Explication

$_=/^([^\W\d])\w*$//(($1 eq"_")+1)
   /^([^\W\d])\w*$/                 matches any string that starts with an underscore or a letter of the alphabet followed by 0 or more alphanumeric + underscore characters. The first character is stored in a capture group
                   /                divide result by
                    (($1 eq"_")+1)  (capture == "_") + 1. This is 1 if the first character was not an underscore and 2 if it was.
$_=                                 assign to $_ and implicitly print

[_a-zA-Z]-> [^\W\d]si perl fonctionne de la même manière que JavaScript, je pense que vous devriez aussi le faire\w*
Downgoat

@Downgoat Semble bien fonctionner avec \w+.
un spaghetto du

matches faux poura
Downgoat

@ Downgoat Ah, c'est vrai. Je vois.
un spaghetto du

1

Python, 84-10% = 76 octets

lambda x:[0,[[.5,1][x[0]>'z'],0][x[0]<'A']][x.replace('_','a').isalnum()]if x else 0

0

JavaScript ES7, 37 octets

x=>!x.match(/\W|^\d/)/2**/^_/.test(x)

Essayez-le en ligne

Comment ça marche:

x=>                                   // Fat arrow function
   !x.match(/\W|^\d/)                 // Gives false if contains non word or starting 
                                      //   with a digit. Booleans in numeric context will 
                                      //   be 0 or 1
                      2**             // 2 to the power of...
                         /^_/.test(x) // gives true if starting with '_'. 
                                      //   true -> 1 -> 2**1 -> 2
                                      //   false -> 0 -> 2**0 -> 1
                     /                // Devide the lValue boolean with the numeric rValue:
                                      // lValue = 0 or 1
                                      // rValue = 2 or 1

Réponse de Port of @ Dennis's Perl


0

Rubis, 44 octets

->(s){s=~/^(_|\d)?\w*$/?$1?$1==?_?0.5:0:1:0}

Vous n'avez pas besoin de parens autour des paramètres pour les lambdas stabby
Pas que Charles

De plus, si vous pouvez trouver un moyen de supprimer ce ternaire supplémentaire, vous pouvez probablement économiser quelques octets. Peut-être /^([a-z_]).../iau lieu de/^(_|\d)?.../
Pas que Charles

@NotthatCharles D'oh ... vous avez raison. Je vais y regarder de plus près quand j'en
aurai l'

0

Ruby, 57 - 10% = 51,3 octets

->(s){case s
when'',/^\d/,/\W/
0
when/^_/
0.5
else
1
end}

Une approche assez naïve


51,3 octets, faites attention. :)
Xesau

@Xesau whoops - embarrassant. Corrigé maintenant :)
Flambino

Vous économisez une énorme quantité d'octets si vous utilisez le chaînage ternaire:->(s){s=~/^$|^\d|\W/?0:s=~/^_/?0.5:1}
Value Ink

@KevinLau True - J'ai déjà ajouté une autre réponse rubis dans cette veine (bien que ce ne soit pas génial non plus)
Flambino

0

Lua, 82 - 10% = 73,8

v=function(s)return(s:match("^[_%a]+[_%w]*$")and 1or 0)*(s:match("_")and.5or 1)end

Cas de test:

print(v("a") == 1) -- true
print(v("1") == 0) -- true
print(v("_") == 0.5) -- true
print(v("") == 0) -- true
print(v("1a") == 0) -- true
print(v("a1") == 1) -- true
print(v("_1") == 0.5) -- true
print(v("_a") == 0.5) -- true
print(v("1_") == 0) -- true
print(v("a_") == 0.5) -- true

Je pense que vous pouvez utiliser STDIN pour manger au moins 10 octets.
Leaky Nun

0

Lua, 68 * .9 = 61,2 octets

s=arg[1]print(s:find("^[%a_][%w_]*$")and(s:find("^_")and.5or 1)or 0)

Prend des arguments sur la ligne de commande

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.