Apakah ini nama variabel yang valid?

23

Objektif

Tulis program atau fungsi yang memeriksa apakah nama variabel valid dan output 1 atau Truejika valid, 0,5 jika valid tetapi dimulai dengan garis bawah (_), dan 0 atau Falsejika tidak valid.

Aturan

  • Nama variabel dalam kebanyakan bahasa valid jika dimulai dengan garis bawah atau huruf (az, AZ, _) dan karakter lainnya adalah garis bawah, huruf, atau angka. (az, AZ, 0-9, _)
  • Output 1 atau Truejika nama variabel valid dan 0 atau Falsejika tidak valid.
  • Namun, itu bukan praktik yang baik untuk memulai variabel dengan garis bawah, jadi kembalikan 0,5 jika dimulai dengan garis bawah dan namanya valid.

Uji Kasus

Memasukkan

abcdefghijklmnop

Keluaran

1

Memasukkan

_test_

Keluaran

0.5 (dimulai dengan garis bawah)

Memasukkan

123abc

Keluaran

0 (dimulai dengan angka)

Memasukkan

A_b1C_23

Keluaran

1

Memasukkan

_!

Keluaran

0 (bukan 0,5 karena tidak valid)

Memasukkan

magical pony1

Keluaran

0 (tidak ada ruang)

Celah standar berlaku.

Ini , jadi kode terpendek menang.

Bonus: -10% jika program / fungsi Anda menghasilkan 0string kosong ( "").

clamchowder314
sumber
1
Bisakah kita menampilkan kebenaran / kepalsuan / apa pun?
CalculatorFeline
5
Hanya mencatat, dengan python, skor di bawah sering digunakan. Kelas membutuhkan fungsi init , fungsi pembantu di kelas terkadang dimulai dengan garis bawah.
Rɪᴋᴇʀ
1
@EasterlyIrk waspadalah terhadap penurunan harga mini; maksudmu __init__; juga, tidak, kelas tidak perlu sebuah __init__tetapi biasanya memiliki satu
kucing
6
Bisakah kita berasumsi bahwa input akan kosong? (Sebagian besar jawaban saat ini tampaknya gagal untuk input kosong.)
Dennis
1
Apakah bonus itu naik atau turun? Jika naik, itu benar-benar tidak layak untuk set jawaban saat ini
Biru

Jawaban:

13

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

Disimpan 4 byte berkat @ edc65

Disimpan 5,6 byte berkat @Mateon

s=>!/^\d|\W|^$/.test(s)/-~(s[0]=='_')
Downgoat
sumber
3
Apakah Anda benar-benar yakin ini bukan perl?
seequ
8

05AB1E , 25 24 20 19 byte

Kode:

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

Penjelasan:

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

Singkatnya, rumus untuk string sdalam pseudocode adalah:

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

Cobalah online!

Menggunakan pengodean CP-1252 .

Adnan
sumber
6

PHP (50 - 10% = 45)

Terima kasih kepada Schism untuk -2 :)

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

Bukan untuk bersaing dengan jawaban golflang, tapi saya pikir saya akan mencobanya.

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

Yang perlu diperhatikan adalah bahwa dalam PHP, tanpa /upengubah, \whanya memilih huruf ASCII. Dalam beberapa bahasa lain / rasa Regex, pola ini tidak akan berfungsi.

Sunting : Saya melihat banyak orang menggunakan \ w dan \ d dalam jawaban mereka, ketika mereka menggunakan bahasa yang menyertakan huruf dan angka selain ASCII. Itu BUKAN teka-teki. Mereka salah. (Belum dapat melakukan downvote / komentar, maaf perlu mengatakannya dengan cara ini.)

Xesau
sumber
Selamat datang di Programming Puzzles dan Code Golf Stack Exchange. Ini jawaban yang bagus; sering tantangan kode-golf berada dalam bahasa dan juga di antara mereka. Saya memberi Anda +1 untuk solusi ini! Sudah selesai dilakukan dengan baik.
wizzwizz4
1
Anda dapat memotong dua karakter dengan [a-z].../i.
Skisma
@ Skisma Terima kasih. Tidak tahu bagaimana saya bisa melupakan itu, biasanya saya pandai teka-teki regex semacam ini :)
Xesau
1
Tentang hasil edit Anda: dapatkah Anda lebih spesifik - bahasa apa? Dalam javascript \dpersis sama dengan [0-9]. \wpersis sama dengan [A-Za-z0-9_] developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/…
edc65
Halaman kode yang digunakan bahasa tidak relevan; selama regex menangani ASCII dengan benar, itu valid. Semua jawaban berbasis regex saat ini berfungsi, setahu saya. Anda tidak mencoba mencocokkan nama variabel dalam bahasa Anda; alih-alih, Anda mencoba mencocokkan nama variabel berdasarkan aturan dalam tantangan.
Mego
5

Retina, 30 - 10% = 27 28 - 10% = 25,2 29 - 10% = 26,1 byte

Kedua versi memenuhi syarat untuk bonus, karena mereka menangani input kosong dengan benar (keluaran 0)

Saya harus memperbaiki bug yang disebabkan oleh salah satu fitur .NET regex, yang menganggap beberapa (baca sebanyak) karakter Unicode sebagai karakter "kata". Untungnya, ini hanya menghabiskan satu byte di kedua versi. Itu hanya datang untuk menambahkan pengubah untuk membuat perilaku pencocokan regex sesuai dengan standar ECMAScript. Lebih lanjut tentang itu di sini .

Versi 28 byte baru 28 , dibuat oleh @ MartinBüttner. Terima kasih!

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

Penjelasan

Pertama, kami memeriksa apakah input dimulai dengan garis bawah. Jika ya, input diduplikasi, dengan baris baru di antaranya. Misalnya: _test_-> _test_\n_test_, di mana \nbaris baru. Kemudian kita mencoba untuk mencocokkan apa pun, yang tidak dimulai dengan angka, namun diikuti oleh sejumlah "kata" karakter ( a-z, A-Z, angka, dan garis bawah) pada setiap baris . Perhatikan bahwa jika input dimulai dengan garis bawah dan diganti menjadi dua baris, ini akan cocok dengan kedua baris. Lalu kami memeriksa apakah kami memiliki 2 pertandingan, dan menggantinya dengan 0.5. Baris kosong atau tidak valid akan selalu menghasilkan 0 kecocokan, dan nama variabel yang valid selalu menghasilkan 1 kecocokan.


30 31 byte versi saya sendiri

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

Penjelasan

Pertama-tama, kami memeriksa apakah masukan dimulai dengan digit atau berisi karakter non-kata (apa pun selain a-z, A-Z, angka dan garis bawah). Jika ya, itu dibuang, karena itu tidak valid. Kemudian kami memeriksa apakah itu dimulai dengan garis bawah. Jika ya, diganti dengan 0.5. Kemudian kita periksa jika dimulai dengan karakter non-digit (pada titik ini karakter pertama adalah baik 0, a-zatau A-Z. Hanya a-zdan A-Znon-digit, jelas). Jika ya, diganti dengan a 1. Kemudian kami memeriksa string kosong dan menggantinya dengan 0.

Cobalah online!
Cobalah online! Versi lama

daavko
sumber
Tunggu, tunggu. Pada ^\D.*tahap itu bisa dimulai dengan 0? Itu aneh.
CalculatorFeline
@CatsAreFluffy Bisa, jika dimulai dengan _dan diganti dengan 0.5. Kemudian dimulai dengan 0.
daavko
Ini salah memberikan 1 untuk input Ψ.
AdmBorkBork
@TimmyD Menarik. Saya tidak mengerti mengapa itu terjadi. Pemeriksaan cepat menunjukkan bahwa \wcocok dengan karakter non-ASCII, yang seharusnya tidak dilakukan (saya sudah mencoba memberikannya ƜƝƞƟƠdan ᎳᎴᎵᎶᎷᎸᎹsebagai input). Saya akan membahas ini nanti. Solusi yang mungkin tampaknya diganti \wdengan [a-zA-Z\d_].
daavko
3

MATL , 27 byte

1)95=2/8M3Y2m+G7M95h4Y2hmA*

Ini berfungsi dalam versi bahasa saat ini (15.0.0) .

Input adalah string dengan tanda kutip tunggal.

Cobalah online!

Penjelasan

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
Luis Mendo
sumber
3

Pyke , 21 byte

(tidak bersaing, menambahkan pengurangan string, berbagai konstanta string)

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

Penjelasan:

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
Biru
sumber
3

Python 3, 36 byte

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

Panjang kode 40 byte dan memenuhi syarat untuk bonus -10% .

Perhatikan bahwa ini hanya akan berfungsi dengan benar untuk halaman kode yang tidak memiliki huruf / digit non-ASCII.

Dennis
sumber
2

Pyth, 27 byte

c!|-rz0++G\_JjkUT}hzJhqhz\_

Test Suite

Biru
sumber
2

Gogh , 29 byte

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

Jalankan menggunakan:

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

Penjelasan

                   “ 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                              ”
Zach Gates
sumber
2

Perl, 21 byte

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

Skor termasuk +1 byte untuk -psakelar. Cobalah di Ideone .

Dennis
sumber
bisakah Anda, katakan -$_||$_=...untuk menjelaskan jawaban kosong? (Menggunakan -karena +adalah no-in perl)
Ven
Tidak, itu kesalahan runtime. Tetapi bahkan jika itu berhasil, itu akan membuat skor saya lebih buruk.
Dennis
Saya hanya melakukan tes minimalis, jadi saya akan mempercayai Anda. Adil bahwa 10% dari 21 byte tidak banyak ..
Ven
2

Pyth, 19 byte

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

Cobalah dengan Pyth Compiler .

Perhatikan bahwa ini hanya akan berfungsi dengan benar untuk halaman kode yang tidak memiliki huruf / digit non-ASCII.

Bagaimana itu bekerja

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.
Dennis
sumber
2

Faktor , 84 * 0,9 = 76,5

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

Berjalan di listener (repl), mendefinisikan kutipan (fungsi anonim) yang mengambil string dan output {0 | 1/2 | 1}.

Mendefinisikannya sebagai sebuah kata berarti 97 karakter:

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

Bagaimana cara kerjanya:

R/ [_a-zA-Z]\w*/ R/ _.*/mendefinisikan dua ekspresi reguler. bi-curry@menerapkan sebagian kutipan [ matches? 1 0 ? ]untuk setiap regex, meninggalkan dua kutipan kari pada stack. bimenerapkan setiap kutipan pada string argumen.

Masing-masing dari itu (kutipan kari) meninggalkan 1 atau 0, tergantung apakah cocok. Yang pertama cocok dengan nama yang terbentuk dengan baik, yang kedua pada nama dimulai dengan garis bawah.

0 = 1 2 ? / Nilai terakhir diganti dengan 1 jika 0, atau 2 jika 1. Kemudian yang pertama (1 atau 0, valid atau tidak) dibagi dengan yang kedua (2 atau 1, dimulai dengan garis bawah atau tidak) .

Ini loooong! Setiap petunjuk untuk menyusut sedikit lebih dihargai ...

Dan saya benci 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

semua tes lulus;)

fede s.
sumber
Hanya ingin tahu, apakah ruang putih benar-benar diperlukan? Saya tidak bisa mengatakan dengan pasti karena saya tidak tahu bahasa atau memiliki penerjemah.
Mama Fun Roll
@MamaFunRoll ya, bukan bahasa golf terbaik! Dalam tradisi Keempat, hanya pembatas yang merupakan karakter spasi.
fede s.
Oh begitu. Di sini, dapatkan upvote.
Mama Fun Roll
Yay, ty! Sekarang untuk menghancurkan kekacauan dengan komentar saya di mana-mana priv!
fede s.
2

Dyalog APL , 19 byte - 10% = 17.1

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

{... ... }fungsi anonim di mana argumen yang benar diwakili oleh
⊃⍵karakter pertama (memberi spasi jika kosong)
'_'=1 jika sama dengan 'underbar, 0 sebaliknya
1+dievaluasi menjadi 2 jika underbar awal, 1 sebaliknya
⎕NC⍵ kelas nama ; -1 jika nama tidak valid, 0 jika tidak terdefinisi (tetapi nama yang valid), 2-9 jika didefinisikan (dan dengan demikian valid)

Adm
sumber
1

Mathematica, 93 byte

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

Jujur saya tidak yakin apakah ini bisa bermain golf lebih lanjut.

LegionMammal978
sumber
1

Perl, 34 + 1 = 35 byte

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

Menggunakan -pbendera.

Penjelasan

$_=/^([^\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
sebuah spaghetto
sumber
[_a-zA-Z]-> [^\W\d]jika perl bekerja sama dengan JavaScript, saya pikir Anda juga harus melakukannya\w*
Downgoat
@Downgoat Tampaknya bekerja dengan baik \w+.
spaghetto
cocok palsu untuka
Downgoat
@Downgoat Ah, benar. Saya melihat.
spaghetto
1

Python, 84 -10% = 76 byte

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

JavaScript ES7, 37 byte

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

Cobalah online

Bagaimana itu bekerja:

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

Port of @ Dennis's Perl menjawab

andlrc
sumber
0

Ruby, 44 byte

->(s){s=~/^(_|\d)?\w*$/?$1?$1==?_?0.5:0:1:0}
Flambino
sumber
Anda tidak perlu parens di sekitar parameter untuk lambdas stabby
Bukan bahwa Charles
Juga jika Anda dapat menemukan cara untuk menjatuhkan terner ekstra itu, Anda mungkin dapat menghemat beberapa byte. Mungkin /^([a-z_]).../ibukannya/^(_|\d)?.../
Bukan Charles
@NotthatCharles D'oh ... kau benar. Saya akan melihatnya lebih dekat ketika saya punya kesempatan
Flambino
0

Ruby, 57 - 10% = 51,3 byte

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

Pendekatan yang cukup naif

Flambino
sumber
51,3 byte, ingatlah. :)
Xesau
@Xesau whoops - memalukan. Diperbaiki sekarang :)
Flambino
Anda menghemat sejumlah besar byte jika Anda menggunakan rantai ternary:->(s){s=~/^$|^\d|\W/?0:s=~/^_/?0.5:1}
Value Ink
@KevinLau Benar - Saya sudah menambahkan jawaban ruby ​​lain dalam nada itu (meskipun tidak bagus juga)
Flambino
0

Lua, 82 - 10% = 73,8

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

Kasus uji:

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
xaxa
sumber
Saya pikir Anda dapat menggunakan STDIN untuk makan setidaknya 10 byte.
Leaky Nun
0

Lua, 68 * .9 = 61.2 byte

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

Membawa argumen di baris perintah

Trebuchette
sumber