Bu geçerli bir değişken adı mı?


23

Amaç

Değişken adının geçerli olup Trueolmadığını ve çıktı 1'in geçerli olup olmadığını denetleyen bir program veya işlev yazın , geçerliyse 0.5, ancak bir alt çizgi (_) ve 0 ile Falsegeçerliyse veya geçerli değilse denetleyin.

kurallar

  • Çoğu dilde değişken adı, alt çizgi veya harfle (az, AZ, _) başlıyorsa ve karakterlerin geri kalanı alt çizgi, harf veya rakam ise geçerlidir. (az, AZ, 0-9, _)
  • Çıktı 1 veya Truedeğişken adı geçerli ve 0 ise veya Falsegeçerli değilse.
  • Bununla birlikte, alt çizgi ile bir değişken başlatmak iyi bir uygulama değildir, bu nedenle alt çizgi ile başlıyorsa ve isim geçerliyse 0.5 döndürün.

Test Kılıfları

Giriş

abcdefghijklmnop

Çıktı

1

Giriş

_test_

Çıktı

0.5 (alt çizgi ile başlar)

Giriş

123abc

Çıktı

0 (bir numara ile başlar)

Giriş

A_b1C_23

Çıktı

1

Giriş

_!

Çıktı

0 (0,5 değil çünkü geçerli değil)

Giriş

magical pony1

Çıktı

0 (boşluksuz)

Standart boşluklar uygulanır.

Bu , yani en kısa kod kazanır.

Bonus: Programınız / fonksiyonunuz 0boş bir dize ( "") çıkarsa,% -10 .


1
Doğruluk / yanlışlık / herhangi bir şey çıktısı alabilir miyiz?
CalculatorFeline

5
Sadece dikkat çekici, python'da puanların altında sıkça kullanılır. Sınıflar bir init fonksiyonuna ihtiyaç duyar , sınıflardaki yardımcı fonksiyonlar bazen alt çizgi ile başlar.
Rɪᴋᴇʀ

1
@ElylyIrk mini-markdown dikkat edin; demek istedin __init__; Ayrıca, hayır, sınıflar yok gerek bir __init__ama genellikle bir var
kedi

6
Girişin boş olmadığını varsayabilir miyiz? (Mevcut cevapların çoğu boş girdi için başarısız görünüyor.)
Dennis,

1
Bu bonus yukarı veya aşağı yuvarlanıyor mu? Eğer öyleyse, şu anki cevaplara sahip olmaya değmez
Blue

Yanıtlar:


13

JavaScript (ES6),% 37 - 10 = 33.3 bayt

@ Edc65 sayesinde 4 bayt kaydedildi

@Mateon sayesinde 5.6 bayt kaydedildi

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

3
Bunun perl olmadığından kesinlikle emin misin?
bkz:

8

05AB1E , 25 24 20 19 bayt

Kod:

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

Açıklama:

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

Kısacası, ssözde koddaki dize için formül :

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

Çevrimiçi deneyin!

CP-1252 kodlamasını kullanır .


6

PHP (% 50 - 10 = 45)

-2 için Schism'e teşekkürler :)

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

Golflang cevaplarıyla rekabet etmek istemem ama yine de deneyeyim dedim.

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

Unutulmaması gereken bir şey, PHP'de, /udeğiştirici olmadan , \wyalnızca ASCII harflerini seçmesidir. Diğer bazı dillerde / Regex lezzetlerinde, bu desen işe yaramaz.

Düzenleme : Cevaplarında ASCII olmayan harfler ve rakamlar içeren bir dil kullandıklarında, cevaplarında \ w ve \ d kullanan birçok insan görüyorum. Bu bulmaca değil. Onlar yanlış. (Henüz oy / yorum yapamam, bu şekilde söylemeniz gerektiğine üzüldüm.)


Programming Puzzles ve Code Golf Stack Exchange'e hoş geldiniz. Bu harika bir cevap; sıklıkla kod golf zorlukları, diller arasında ve aralarındadır. Bu çözüm için sana + 1 veriyorum! Aferin.
wizzwizz4

1
İle iki karakteri tıraş edebilirsiniz [a-z].../i.
Schism

@Schism Teşekkürler. Bunu nasıl unutabildiğimi bilmiyorum, genellikle bu tür regex bulmacalarında
iyiyim

1
Düzenlemeniz hakkında: daha belirgin olabilir misiniz - hangi dilleri? Javascript \dtam olarak aynıdır [0-9]. \wexactlly aynıdır [A-Za-z0-9_] developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/...
edc65

Dilin kullandığı kod sayfası önemli değil; Regex ASCII'yi düzgün bir şekilde kullandığı sürece geçerlidir. Mevcut regex tabanlı cevapların tümü benim bildiğim kadarıyla işe yarıyor. Dilinizde bir değişken ismini eşleştirmeye çalışmıyorsunuz; bunun yerine, meydan okumadaki kuralları temel alan değişken bir adla eşleşmeye çalışıyorsunuz.
Mego

5

Retina, % 30 - 10 = 27% 28 - 10 = 25.2% 29 - 10 = 26.1 bayt

Her iki sürüm de boş girişi doğru şekilde ele aldığından bonuslara hak kazanır (çıkışlar 0)

Bazı (çok okunan) Unicode karakterleri "kelime" karakterleri olarak kabul eden .NET regex özelliklerinden birinin neden olduğu bir hatayı düzeltmek zorunda kaldım. Neyse ki, bu bana her iki versiyonda da sadece bir bayta mal oldu. Yalnızca regex eşleştirme davranışını ECMAScript standartlarına uygun hale getirmek için bir değiştirici eklemeye geldi. Bunun hakkında daha fazlası burada .

@ MartinBüttner tarafından yapılan yeni 28 29 bayt sürümü. Teşekkürler!

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

açıklama

İlk önce, girişin alt çizgi ile başlayıp başlamadığını kontrol ederiz. Eğer öyleyse, giriş arasında yeni bir satır olacak şekilde giriş kopyalanır. Örneğin: _test_-> _test_\n_test_, \nyeni satır nerede ? Sonra bir sayı ile başlamaz şey, maç çalışıyorum, ama "kelimesi" karakterlerinin (herhangi bir sayıda takip eder a-z, A-Z, rakam ve alt çizgi) her satırda . Girdi bir alt çizgi ile başladıysa ve iki satıra değiştirilirse, bunun her iki satıra eşleşeceğini unutmayın. Sonra 2 eşleşme olup olmadığını kontrol ettik ve değiştirdik 0.5. Boş veya geçersiz satır her zaman 0 eşleşme verir ve geçerli değişken adları her zaman 1 eşleşme verir.


Kendi 30 31 bayt versiyonum

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

açıklama

Girdi bir rakam ile başlar veya olmayan bir kelime karakterle (başka bir şey içeriyorsa Her şeyden önce, biz kontrol a-z, A-Z, rakamlar ve alt çizgi). Varsa atılır, çünkü geçersiz. Sonra bir alt çizgi ile başlayıp başlamadığını kontrol ederiz. Olursa, yerini alır 0.5. Olmayan bir basamaklı karakteri ile başlarsa Sonra kontrol (ilk karakter ya da bu noktada 0, a-zya da A-Z. Sadece a-zve A-Zbelli olmayan, basamak vardır). Varsa, a ile değiştirilir 1. Sonra boş dizgiyi kontrol edip, yerine koyuyoruz 0.

Çevrimiçi deneyin!
Çevrimiçi deneyin! Eski versiyon


Bekle bekle bekle. At ^\D.*sahnede o 0 ile başlayabilir? Bu tuhaf.
Hesap MakinesiFeline

@CatsAreFluffy Eğer bir ile başladıysa _ve ile değiştirildi 0.5. Sonra 0 ile başlar.
daavko

Bu yanlış giriş için 1 verir Ψ.
AdmBorkBork,

@TimmyD İlginç. Neden böyle yaptığını anlamıyorum. Hızlı kontrol, \wASCII olmayan karakterlerle eşleşmesi gerektiğini, bunun yapmaması gerekenleri belirtir (bunu vermeye çalıştım ƜƝƞƟƠve ᎳᎴᎵᎶᎷᎸᎹgirdi olarak). Bunu daha sonra inceleyeceğim. Olası bir çözüm yerine görünüyor \wile [a-zA-Z\d_].
daavko

3

MATL , 27 bayt

1)95=2/8M3Y2m+G7M95h4Y2hmA*

Bu , dilin geçerli sürümünde (15.0.0) çalışır .

Giriş, tek tırnaklı bir dizedir.

Çevrimiçi deneyin!

açıklama

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 bayt

(rekabetçi olmayan, eklenen dize çıkarma, çeşitli dize sabitleri)

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

Açıklama:

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 bayt

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

Kod 40 bayt uzunluğunda ve % -10 bonus için uygun .

Bunun sadece ASCII olmayan harfler / rakamlar içermeyen kod sayfaları için doğru çalışacağını unutmayın.



2

Gogh , 29 bayt

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

Kullanarak çalıştır:

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

açıklama

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

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

Puan geçiş için +1 bayt içerir -p. Üzerinde Deneyin Ideone .


Eğer, demek olabilirdi -$_||$_=...boş cevap hesaba? ( -çünkü +perl'de bir noop olduğu için)
Ven

Hayır, bu bir çalışma zamanı hatası. Fakat işe yarasa bile, puanımı daha da kötüleştirirdi.
Dennis,

Sadece minimalist testler yaptım, o yüzden sana güveneceğim. Adil, 21 baytın% 10'unun pek olmadığını ..
Ven

2

Pyth, 19 bayt

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

Pyth Derleyici ile deneyin .

Bunun sadece ASCII olmayan harfler / rakamlar içermeyen kod sayfaları için doğru çalışacağını unutmayın.

Nasıl çalışır

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

Faktör , 84 * 0.9 = 76,5

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

Dinleyicide çalışır (repl), bir dizge alır ve çıktılar {0 | 1/2 | 1}.

Bir kelime olarak tanımlamak 97 karakter:

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

O nasıl çalışır:

R/ [_a-zA-Z]\w*/ R/ _.*/İki normal ifadeyi tanımlar. bi-curry@Kısmi olarak teklifi [ matches? 1 0 ? ]her regex'e uygular ve yığında iki adet köri alıntı bırakır. biher teklifi argüman dizgisine uygular.

Bunların her biri (kavisli alıntılar), eşleşip eşleşmediklerine bağlı olarak 1 veya 0 değerini bırakır. İlki iyi biçimlendirilmiş isimlerle, ikincisi alt çizgi ile başlayan isimlerle eşleşir.

0 = 1 2 ? / En son değer 0 ise 1, 2 ise 1 olur .

Bu loooong! Küçülen bir işaretçi biraz daha takdir ediyor ...

Ve regexps'ten nefret ediyorum!

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

tüm test geçişi;)


Sadece merak ediyorum, boşluk gerçekten gerekli mi? Dili bilmiyorum veya tercümana sahip olduğum için kesin olarak söyleyemem.
Mama Fun Roll

@MamaFunRoll evet, en iyi golf dili değil! Forth geleneğinde sadece sınırlayıcı boşluk karakterleridir.
fede s.

Ah anlıyorum. İşte, bir oy ver.
Mama Fun Roll

Yay, ty! Şimdi benim yorum-her yerde özel tahribat kırmak için!
fede s.

2

Dyalog APL , 19 bayt -% 10 = 17.1

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

{... ... }doğru bağımsız değişken ile temsil edilir anonim işlev
⊃⍵ilk karakter (alan boş ise verir)
'_'=alt çizgi 'eşittir 1 ise, aksi halde 0
1+ilk alt çizgi, 1, aksi takdirde 2'ye değerlendirir
⎕NC⍵ sınıfı adı ; -1 ise geçersiz ad, tanımsız ise 0 (ancak geçerli ad), tanımlandıysa 2-9 (ve dolayısıyla geçerli)


1

Mathematica, 93 bayt

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

Dürüstçe bu olup olmadığından emin değilim olabilir ayrıca golfed edilecek.


1

Perl, 34 + 1 = 35 bayt

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

-pBayrağı kullanır .

açıklama

$_=/^([^\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]perl, JavaScript ile aynı şekilde çalışırsa, sanırım yapmanız gerekeceğini de düşünüyorum\w*
Downgoat

@Downgoat ile iyi çalışıyor gibi görünüyor \w+.
bir

ile yanlış eşleşmeleria
Downgoat

@ Downgoat Ah, doğru. Anlıyorum.
bir

1

Python,% 84-10 = 76 bayt

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

0

JavaScript ES7, 37 bayt

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

Çevrimiçi deneyin

Nasıl çalışır:

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

@ Dennis'in Perl cevabı limanı


0

Ruby, 44 bayt

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

Stabby lambdas için parametreleri etrafında parens gerekmez
değil Charles

Ayrıca, bu ekstra üçlüyü atmanın bir yolunu bulabilirseniz, muhtemelen bazı baytları kaydedebilirsiniz. Belki /^([a-z_]).../iyerine/^(_|\d)?.../
değil Charles

@HotthatCharles D'oh ... haklısın.
Şansım

0

Ruby, 57 - 10% = 51.3 bayt

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

Oldukça saf bir yaklaşım


51.3 bayt, dikkat et. :)
Xesau

@ Xesau whoops - utanç verici. Şimdi düzeltildi :)
Flambino

Üçlü zincirleme kullanıyorsanız büyük miktarda bayttan tasarruf edersiniz:->(s){s=~/^$|^\d|\W/?0:s=~/^_/?0.5:1}
Value Ink

@KevinLau Doğru - Zaten o damarda başka bir yakut cevabı ekledim (ya da harika olmasa da)
Flambino

0

Lua,% 82 - 10 = 73.8

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

Test Durumları:

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

En az 10 bayt yemek için STDIN'i kullanabileceğinizi düşünüyorum.
Leaky Nun

0

Lua, 68 * .9 = 61.2 bayt

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

Komut satırında argümanlar alır

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.