Czy to jest poprawna nazwa zmiennej?


23

Cel

Napisz program lub funkcję, która sprawdzi, czy nazwa zmiennej jest poprawna i wyświetli 1 lub Truejeśli jest poprawna, 0,5 jeśli jest poprawna, ale zaczyna się od znaku podkreślenia (_), i 0 lub Falsejeśli nie jest poprawna.

Zasady

  • Nazwa zmiennej w większości języków jest poprawna, jeśli zaczyna się od znaku podkreślenia lub litery (az, AZ, _), a pozostałe znaki to podkreślenia, litery lub cyfry. (az, AZ, 0–9, _)
  • Wyjście 1 lub Truejeśli nazwa zmiennej jest poprawna, a 0 lub Falsejeśli nie jest poprawna.
  • Jednak nie jest dobrą praktyką rozpoczynanie zmiennej znakiem podkreślenia, więc zwróć 0,5, jeśli zaczyna się znakiem podkreślenia i nazwa jest poprawna.

Przypadki testowe

Wkład

abcdefghijklmnop

Wydajność

1

Wkład

_test_

Wydajność

0.5 (zaczyna się od podkreślenia)

Wkład

123abc

Wydajność

0 (zaczyna się od liczby)

Wkład

A_b1C_23

Wydajność

1

Wkład

_!

Wydajność

0 (nie 0,5, ponieważ nie jest poprawny)

Wkład

magical pony1

Wydajność

0 (bez odstępów)

Obowiązują standardowe luki .

To jest , więc wygrywa najkrótszy kod.

Premia: -10%, jeśli program / funkcja wyświetla 0pusty ciąg znaków ( "").


1
Czy możemy wydać prawdę / fałsz / cokolwiek?
CalculatorFeline,

5
Wystarczy zauważyć, że w python często używane są wyniki poniżej. Klasy potrzebują funkcji init, funkcje pomocnicze w klasach są czasami rozpoczynane znakiem podkreślenia.
Rɪᴋᴇʀ

1
@EasterlyIrk uważaj na mini-markdown; miałeś na myśli __init__; też nie, klasy nie muszą__init__ ale zazwyczaj mają jeden
kot

6
Czy możemy założyć, że dane wejściowe będą niepuste? (Większość obecnych odpowiedzi wydaje się zawodzić przy pustych danych wejściowych.)
Dennis,

1
Czy ta premia zaokrągla w górę czy w dół? Jeśli tak, to naprawdę nie warto mieć przy obecnym zestawie odpowiedzi
Blue

Odpowiedzi:


13

JavaScript (ES6), 37–10% = 33,3 bajtów

Zaoszczędzono 4 bajty dzięki @ edc65

Zaoszczędź 5,6 bajtów dzięki @Mateon

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

3
Czy jesteś absolutnie pewien, że to nie perl?
patrz

8

05AB1E , 25 24 20 19 bajtów

Kod:

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

Wyjaśnienie:

¬                     # 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.

Krótko mówiąc, wzór na ciąg sw pseudokodzie jest następujący:

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

Wypróbuj online!

Wykorzystuje kodowanie CP-1252 .


6

PHP (50-10% = 45)

Dzięki Schism za -2 :)

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

Nie konkurować z odpowiedziami golfa, ale pomyślałem, że i tak spróbuję.

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

Należy zauważyć, że w PHP bez /umodyfikatora \wwybiera się tylko litery ASCII. W niektórych innych wersjach językowych / odmianach Regex ten wzór nie działa.

Edycja : Widzę wiele osób używających \ wi id w swoich odpowiedziach, gdy używają języka zawierającego litery i cyfry spoza ASCII. To NIE jest układanka. Oni są źli. (Nie mogę jeszcze głosować / komentować, przepraszam, że muszę to powiedzieć w ten sposób.)


Witamy w Programowaniu łamigłówek i wymianie stosów kodów golfowych. To świetna odpowiedź; często wyzwania związane z golfem są zarówno w językach, jak i między nimi. Daję +1 za to rozwiązanie! Dobra robota.
wizzwizz4,

1
Możesz ogolić dwie postacie za pomocą [a-z].../i.
Schizm

@ Schizm Dziękuję. Nie wiem, jak udało mi się o tym zapomnieć, zazwyczaj jestem dobry w tego rodzaju łamigłówkach regularnych :)
Xesau

1
O swojej edycji: czy możesz być bardziej szczegółowy - w jakich językach? W javascript \djest dokładnie taki sam jak [0-9]. \wjest dokładnie taki sam jak [A-Za-z0-9_] developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/…
edc65

Strona kodowa używana przez język jest nieistotna; dopóki regex poprawnie obsługuje ASCII, jest on poprawny. O ile wiem, wszystkie obecne odpowiedzi oparte na wyrażeniach regularnych działają. Nie próbujesz dopasować nazwy zmiennej w swoim języku; raczej próbujesz dopasować nazwę zmiennej w oparciu o reguły w wyzwaniu.
Mego

5

Siatkówka, 30-10 % = 27 28-10% = 25,2 29-10 % = 26,1 bajtów

Obie wersje kwalifikują się do premii, ponieważ poprawnie obsługują puste dane wejściowe (dane wyjściowe 0)

Musiałem naprawić błąd spowodowany jedną z funkcji wyrażenia regularnego .NET, która traktuje niektóre (odczytane) znaki Unicode jako znaki „słowne”. Na szczęście kosztowało mnie to tylko jeden bajt w obu wersjach. Sprowadzało się to tylko do dodania modyfikatora, aby zachowanie dopasowania wyrażenia regularnego było zgodne ze standardami ECMAScript. Więcej o tym tutaj .

Nowa 28 29-bajtowa wersja autorstwa @ MartinBüttner. Dzięki!

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

Wyjaśnienie

Najpierw sprawdzamy, czy dane wejściowe zaczynają się od znaku podkreślenia. Jeśli tak, dane wejściowe są duplikowane, a pomiędzy nimi znajduje się nowa linia. Na przykład: _test_-> _test_\n_test_, gdzie \njest nowa linia. Następnie staramy się dopasować niczego, że nie rozpoczyna się od liczby, ale jest po dowolnej liczbie znaków „Słowo” ( a-z, A-Z, cyfry i podkreślenia) na każdej linii . Zauważ, że jeśli dane wejściowe rozpoczęły się znakiem podkreślenia i zostały zastąpione dwoma liniami, będzie to pasować do obu linii. Następnie sprawdzamy, czy mieliśmy 2 mecze i zastępujemy je 0.5. Pusty lub niepoprawny wiersz zawsze daje 0 dopasowań, a prawidłowe nazwy zmiennych zawsze dają 1 dopasowanie.


Moja własna 30 31-bajtowa wersja

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

Wyjaśnienie

Przede wszystkim, możemy sprawdzić, czy wejściowe zaczyna się od cyfry lub zawiera znak zakaz słowo (coś innego niż a-z, A-Z, cyfr i znaków podkreślenia). Jeśli tak, jest odrzucane, ponieważ jest nieprawidłowe. Następnie sprawdzamy, czy zaczyna się od podkreślenia. Jeśli tak, zostanie zastąpione przez 0.5. Następnie sprawdzamy, czy zaczyna się niż cyfra (w tym momencie pierwszy znak jest albo 0, a-zalbo A-Z. Tylko a-zi A-Zsą non-cyfry, oczywiście). Jeśli tak, zostanie zastąpione przez 1. Następnie sprawdzamy, czy jest pusty ciąg i zastępujemy go 0.

Wypróbuj online!
Wypróbuj online! Stara wersja


Czekaj czekaj czekaj. Na ^\D.*etapie może zaczynać się od 0? To jest dziwne.
CalculatorFeline,

@CatsAreFluffy Może, jeśli zaczął się od _a został zastąpiony przez 0.5. Potem zaczyna się od 0.
daavko,

To niepoprawnie daje 1 na wejście Ψ.
AdmBorkBork

@TimmyD Ciekawe. Nie rozumiem, dlaczego to robi. Szybkie check wskazuje, że \wjest dopasowanie znaków spoza ASCII, których nie należy robić (Starałem się dać go ƜƝƞƟƠi ᎳᎴᎵᎶᎷᎸᎹjako wejście). Zajmę się tym później. Możliwym rozwiązaniem wydaje się zastąpienie \wz [a-zA-Z\d_].
daavko

3

MATL , 27 bajtów

1)95=2/8M3Y2m+G7M95h4Y2hmA*

Działa to w bieżącej wersji (15.0.0) języka.

Dane wejściowe to ciąg z pojedynczymi cudzysłowami.

Wypróbuj online!

Wyjaśnienie

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 bajtów

(niekonkurencyjne, dodane odejmowanie ciągów, różne stałe ciągów)

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

Wyjaśnienie:

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 bajtów

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

Kod ma 40 bajtów i kwalifikuje się do premii -10% .

Pamiętaj, że będzie to działać poprawnie tylko dla stron kodowych, które nie mają liter / cyfr spoza ASCII.



2

Gogh , 29 bajtów

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

Uruchom używając:

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

Wyjaśnienie

                   “ 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 bajtów

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

Wynik zawiera +1 bajt dla -pprzełącznika. Wypróbuj na Ideone .


mógłbyś, powiedzmy, -$_||$_=...wziąć pod uwagę pustą odpowiedź? (używając -ponieważ +jest noop w perlu)
Ven

Nie, to błąd czasu wykonywania. Ale nawet gdyby zadziałało, pogorszyłoby to mój wynik.
Dennis

Zrobiłem tylko minimalistyczne testy, więc mogę ci zaufać. Jasne, że 10% z 21 bajtów to niewiele…
Ven

2

Pyth, 19 bajtów

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

Wypróbuj z kompilatorem Pyth .

Pamiętaj, że będzie to działać poprawnie tylko dla stron kodowych, które nie mają liter / cyfr spoza ASCII.

Jak to działa

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

Współczynnik 84 * 0,9 = 76,5

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

Działa na detektorze (repl), definiuje cytat (funkcja anonimowa), który pobiera ciąg znaków i generuje wyniki {0 | 1/2 | 1}.

Zdefiniowanie go jako słowa to 97 znaków:

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

Jak to działa:

R/ [_a-zA-Z]\w*/ R/ _.*/definiuje dwa wyrażenia regularne. bi-curry@częściowo stosuje cytat [ matches? 1 0 ? ]do każdego wyrażenia regularnego, pozostawiając dwa curry cytaty na stosie. bistosuje każdy cytat do ciągu argumentu.

Każda z nich (curry notowania) pozostawia 1 lub 0, w zależności od tego, czy pasowały. Pierwsze dopasowania w dobrze uformowanych nazwach, drugie w nazwach rozpoczynających się od podkreślenia.

0 = 1 2 ? / Ostatnia wartość jest zastępowana 1, jeśli było 0, lub 2, jeśli było 1. Następnie pierwsza (1 lub 0, ważna lub nie) jest dzielona przez drugą (2 lub 1, zaczyna się od podkreślenia lub nie) .

To jest długie! Wszelkie wskazówki dotyczące zmniejszania się są bardziej doceniane ...

I nienawidzę wyrażeń regularnych!

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

wszystkie testy zaliczone;)


Zastanawiam się, czy białe znaki są naprawdę konieczne? Nie mogę powiedzieć tego na pewno, ponieważ nie znam języka ani nie mam tłumacza.
Mama Fun Roll

@MamaFunRoll tak, nie najlepszy język golfa! W tradycji Forth jedynym ogranicznikiem są znaki białych znaków.
Fede s.

Rozumiem. Tutaj, głosuj pozytywnie.
Mama Fun Roll

Tak, ty! Teraz zrób spustoszenie moim komentarzem - wszędzie priv!
Fede s.

2

Dyalog APL , 19 bajtów - 10% = 17,1

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

{... ... }funkcji anonimowej gdzie prawo argumentem jest reprezentowany przez
⊃⍵pierwszego znaku (jeśli daje przestrzeń pusta)
'_'=1 jeśli równa „Underbar, 0 w przeciwnym razie
1+ma wartość 2, jeżeli początkowa underbar, 1 inaczej
⎕NC⍵ nazwa klasy ; -1, jeśli nieprawidłowa nazwa, 0, jeśli niezdefiniowana (ale ważna nazwa), 2-9, jeśli zdefiniowana (a zatem ważna)


1

Mathematica, 93 bajty

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

Naprawdę nie jestem pewien, czy można dalej grać w golfa.


1

Perl, 34 + 1 = 35 bajtów

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

Używa -pflagi.

Wyjaśnienie

$_=/^([^\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]jeśli perl działa tak samo jak JavaScript, myślę, że musiałbyś to zrobić\w*
Downgoat

@Downgoat Wygląda na to, że działa dobrze \w+.
spaghetto

pasuje do fałszua
Downgoat

@Downgoat Ah, racja. Widzę.
spaghetto

1

Python, 84-10% = 76 bajtów

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

0

JavaScript ES7, 37 bajtów

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

Wypróbuj online

Jak to działa:

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

Odpowiedź Perla na port @ Dennisa


0

Rubinowy, 44 bajty

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

Nie potrzebujesz parens wokół parametrów dla mocnych lambdas
Nie, że Charles

Również jeśli potrafisz wymyślić sposób na usunięcie tej dodatkowej trójki, możesz prawdopodobnie zaoszczędzić trochę bajtów. Może /^([a-z_]).../izamiast/^(_|\d)?.../
Nie, że Charles

@NotthatCharles D'oh ... masz rację. Przyjrzę się temu, kiedy będę miał okazję
Przyjrzę się temu,

0

Rubinowy, 57–10% = 51,3 bajtów

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

Całkiem naiwne podejście


51,3 bajtów, pamiętaj. :)
Xesau

@Xesau whoops - żenujące. Naprawiono teraz :)
Flambino

Zaoszczędzasz ogromną ilość bajtów, jeśli używasz trójskładnikowego łączenia:->(s){s=~/^$|^\d|\W/?0:s=~/^_/?0.5:1}
Wartość tuszu

@KevinLau Prawda - dodałem już inną rubinową odpowiedź w tym stylu (choć też nie jest świetna)
Flambino

0

Lua, 82–10% = 73,8

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

Przypadki testowe:

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

Myślę, że możesz użyć STDIN do zjedzenia co najmniej 10 bajtów.
Leaky Nun

0

Lua, 68 * .9 = 61,2 bajtów

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

Bierze argumenty w wierszu poleceń

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.