Це дійсне ім'я змінної?


23

Об'єктивна

Напишіть програму або функцію, яка перевіряє, чи ім'я змінної є дійсним та виводить 1, або Trueякщо воно дійсне, 0,5, якщо воно дійсне, але починається з підкреслення (_), і 0 або Falseякщо воно недійсне.

Правила

  • Ім'я змінної в більшості мов є дійсним, якщо воно починається з підкреслення або літери (az, AZ, _), а решта символів є або підкресленнями, літерами або цифрами. (az, AZ, 0-9, _)
  • Вихід 1 або Trueякщо ім'я змінної є дійсним і 0 або Falseякщо недійсне.
  • Однак запустити змінну з підкреслення не дуже добре, тому поверніть 0,5, якщо вона починається з підкреслення і ім'я є дійсним.

Випробування

Вхідні дані

abcdefghijklmnop

Вихід

1

Вхідні дані

_test_

Вихід

0.5 (починається з підкреслення)

Вхідні дані

123abc

Вихід

0 (починається з числа)

Вхідні дані

A_b1C_23

Вихід

1

Вхідні дані

_!

Вихід

0 (не 0,5, тому що це недійсно)

Вхідні дані

magical pony1

Вихід

0 (без пробілів)

Застосовуються стандартні лазівки .

Це , тому найкоротший код виграє.

Бонус: -10%, якщо ваша програма / функція видає 0порожній рядок ( "").


1
Чи можемо ми випустити правду / фальш / що-небудь?
CalculatorFeline

5
Відзначимо, в пітоні часто застосовуються під партитури. Класам потрібна функція init, функції помічників у класах іноді починаються з підкреслення.
Rɪᴋᴇʀ

1
@EasterlyIrk остерігайтеся міні-відмітки; ви мали на увазі __init__; Крім того, ні, заняття не потрібні , __init__але зазвичай мають одного
кішка

6
Чи можна припустити, що вхід буде не порожнім? (Більшість поточних відповідей здаються невдалими для порожнього введення.)
Денніс

1
Цей бонус кругляє вгору чи вниз? Якщо вгору, насправді не варто мати відповіді на поточний набір відповідей
Blue

Відповіді:


13

JavaScript (ES6), 37 - 10% = 33,3 байт

Збережено 4 байти завдяки @ edc65

Збережено 5,6 байти завдяки @Mateon

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

3
Ви абсолютно впевнені, що це не перл?
seequ

8

05AB1E , 25 24 20 19 байт

Код:

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

Пояснення:

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

Коротше кажучи, формула для рядка sв псевдокоді:

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

Спробуйте в Інтернеті!

Використовує кодування CP-1252 .


6

PHP (50 - 10% = 45)

Дякую Шизму за -2 :)

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

Не конкурувати з відповідями на гольфланг, але я подумав, що все-таки спробую.

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

Що слід зазначити, що в PHP, без /uмодифікатора, \wвибираються лише ASCII літери. Для деяких інших мов / ароматів Regex ця схема не працюватиме.

Редагувати : Я бачу дуже багато людей, які використовують у своїх відповідях \ w та \ d, коли вони використовують мову, що включає також літери та цифри, що не належать до ASCII. Це НЕ головоломка. Вони помиляються. (Поки що не вдається подати коментар / коментувати. Вибачте, що потрібно сказати це так.)


Ласкаво просимо до головоломки програмування та обміну стека коду для гольфу. Це чудова відповідь; часто проблеми з кодовим гольфом знаходяться як серед мов, так і між ними. Я даю вам +1 за це рішення! Молодці.
wizzwizz4

1
Ви можете поголити двох символів за допомогою [a-z].../i.
Схизм

@Schism Дякую Не знаю, як мені вдалося це забути, як правило, я хороший у таких головоломках :)
Xesau

1
Про вашу редагування: чи можете ви бути більш конкретними - якими мовами? У javascript \dточно такий же, як у [0-9]. \wточно такий же, як [A-Za-z0-9_] developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/…
edc65

Сторінка коду, якою використовується мова, не має значення; до тих пір, поки регулярно виражена графіка належним чином обробляє ASCII, вона дійсна. Наскільки мені відомі всі відповіді на основі регулярних виразів. Ви не намагаєтеся відповідати імені змінної у своїй мові; швидше, ви намагаєтеся зіставити ім'я змінної на основі правил у виклику.
Мего

5

Сітківка, 30 - 10% = 27 28 - 10% = 25,2 29 - 10% = 26,1 байт

Обидві версії мають право на бонус, оскільки вони правильно обробляють порожній ввід (виходи 0)

Мені довелося виправити помилку, викликану однією з функцій .NET regex, яка вважає деякі (читати стільки) символів Unicode як "word" символи. На щастя, це коштувало мені лише одного байта в обох версіях. Це зводилося лише до додавання модифікатора, щоб зробити поведінку збігу регулярних виразів відповідним стандартам ECMAScript. Більше про це тут .

Нова 28 -байтна версія, виготовлена ​​@ MartinBüttner. Спасибі!

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

Пояснення

Спочатку ми перевіряємо, чи введення починається з підкреслення. Якщо це так, введення дублюється з новим рядком між ними. Наприклад: _test_-> _test_\n_test_, де \nзнаходиться новий рядок. Тоді ми намагаємося відповідати що - небудь, що починається не з числа, але слід будь-яку кількість «слів» символів ( a-z, A-Zцифри і символ підкреслення) в кожному рядку . Зауважте, що якщо введення почалося з підкреслення і було замінено на два рядки, це буде відповідати обом рядкам. Потім ми перевіряємо, чи було у нас 2 матчі, і замінюємо їх 0.5. Порожній або недійсний рядок завжди матиме 0 збігів, а дійсні імена змінних завжди дають 1 збіг.


Моя власна 30 -байтна версія

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

Пояснення

Перш за все, ми перевіряємо , якщо вхід починається з цифри або містить не слово символ (нічого, крім a-z, A-Z, цифри і підкреслення). Якщо це зробити, його відкидають, оскільки він недійсний. Потім перевіряємо, чи не починається це з підкреслення. Якщо це так, його замінюють на 0.5. Потім ми перевіряємо , якщо вона починається з Нецифра характеру (в цей момент перший символ є або 0, a-zабо A-Z. Тільки a-zі A-ZНЕ мали цифри, очевидно). Якщо це так, його замінюють на 1. Потім перевіряємо наявність порожнього рядка і замінюємо його 0.

Спробуйте в Інтернеті!
Спробуйте в Інтернеті! Стара версія


Зачекайте. На ^\D.*етапі це може початися з 0? Це дивно.
CalculatorFeline

@CatsAreFluffy Це може, якщо він почався з a _і був замінений на 0.5. Потім він починається з 0.
daavko

Це неправильно дає 1 для введення Ψ.
AdmBorkBork

@TimmyD Цікаво. Я не розумію, чому це робиться. Швидка перевірка показує, що \wце відповідність символів, що не належать до ASCII, що не повинно робити (я намагався дати це ƜƝƞƟƠі ᎳᎴᎵᎶᎷᎸᎹяк введення). Я розгляну це пізніше. Можливе рішення здається заміною \wна [a-zA-Z\d_].
daavko

3

MATL , 27 байт

1)95=2/8M3Y2m+G7M95h4Y2hmA*

Це працює в поточній версії (15.0.0) мови.

Введення - це рядок з одинарними лапками.

Спробуйте в Інтернеті!

Пояснення

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

Пайк , 21 байт

(неконкурентні, додані рядкові віднімання, різні рядкові константи)

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

Пояснення:

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 байт

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

Код завдовжки 40 байт і відповідає бонусу -10% .

Зауважте, що це буде правильно працювати лише для кодових сторінок, на яких немає літер / цифр, що не належать до ASCII.



2

Гог , 29 байт

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

Запустити за допомогою:

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

Пояснення

                   “ 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 байт

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

Оцінка включає +1 байт для -pкомутатора. Спробуйте це на Ideone .


ви могли б сказати, -$_||$_=...щоб пояснити порожню відповідь? (використовуючи, -тому що +це noop in perl)
Вен

Ні, це помилка під час виконання. Але навіть якби це спрацювало, це зробило б мій результат гіршим.
Денніс

Я робив лише мінімалістичні тести, тому я вам довіряю. Справедливо, що 10% 21 байта - це не дуже багато ..
Вен,

2

Pyth, 19 байт

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

Спробуйте це з компілятором Pyth .

Зауважте, що це буде правильно працювати лише для кодових сторінок, на яких немає літер / цифр, що не належать до ASCII.

Як це працює

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

Фактор , 84 * 0,9 = 76,5

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

Працює на слухачі (repl), визначає лапки (анонімну функцію), яка займає рядок і виводить {0 | 1/2 | 1}.

Визначивши це як слово, це 97 символів:

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

Як це працює:

R/ [_a-zA-Z]\w*/ R/ _.*/визначає два регулярні вирази. bi-curry@частково застосовує цитату [ matches? 1 0 ? ]до кожного регулярного виразу, залишаючи дві викладені цитати на стеці.biзастосовує кожну цитату до рядка аргументу.

Кожна з цих (виправлених пропозицій) залишає або 1, або 0, залежно від того, якщо вони збігаються. Перші збіги на добре сформованих іменах, другі на імена, що починаються з підкреслення.

0 = 1 2 ? / Останнє значення замінюється на 1, якщо воно було 0, або на 2, якщо воно було 1. Тоді перше (1 або 0, дійсне чи ні) ділиться на друге (2 або 1, починається з підкреслення чи ні) .

Це лубун! Будь-які вказівки на скорочення трохи більше оцінюються ...

І я ненавиджу регулярні вирази!

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

весь тест-пропуск;)


Просто цікаво, чи справді необхідний пробіл? Я не можу сказати точно, оскільки не знаю мови чи перекладача.
Mama Fun Roll

@MamaFunRoll Так, не найкраща мова для гольфу! У традиції Forth лише роздільники знаків пробілу.
федерація.

О Я бачу. Ось, майте нагороду.
Mama Fun Roll

Так, ти! Тепер зламати хаос з моїм коментарем - скрізь прив!
федерація.

2

Діалог APL , 19 байт - 10% = 17,1

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

{... ... }анонімну функцію , де право аргумент , представлений
⊃⍵першим символом (дає простір , якщо порожньо)
'_'=1 , якщо значення «підкреслення, 0 в іншому випадку має
1+значення 2 , якщо початкове підкреслення, 1 в іншому випадку
⎕NC⍵ ім'я класу ; -1 якщо недійсне ім'я, 0, якщо не визначено (але дійсне ім'я), 2-9, якщо визначено (і, таким чином, дійсно)


1

Математика, 93 байти

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

Я, чесно кажучи, не впевнений, чи можна далі займатися гольфом.


1

Perl, 34 + 1 = 35 байт

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

Використовує -pпрапор.

Пояснення

$_=/^([^\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, я думаю, вам також доведеться це робити\w*
Downgoat

@Downgoat Здається, добре працює \w+.
спагето

фальшиві матчі заa
Downgoat

@Downgoat Ага, правильно. Розумію.
спагетто

1

Python, 84 -10% = 76 байт

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

0

JavaScript ES7, 37 байт

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

Спробуйте в Інтернеті

Як це працює:

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

Відповідь Perl @ Dennis's Perl


0

Рубін, 44 байти

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

Вам не потрібні паролі навколо параметрів для стійких лямбд
Не те, щоб Чарльз

Крім того, якщо ви можете знайти спосіб скинути цей додатковий потрійний, ви, ймовірно, можете зберегти кілька байт. Може /^([a-z_]).../iзамість цього/^(_|\d)?.../
Не те, щоб Чарльз

@NotthatCharles D'oh ... ти маєш рацію. Я детальніше ознайомлюсь, коли
матиму

0

Ruby, 57 - 10% = 51,3 байт

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

Досить наївний підхід


51,3 байт, пам'ятайте. :)
Xesau

@Xesau whoops - незбагненний. Виправлено зараз :)
Фламбіно

Ви економите величезну кількість байтів, якщо використовуєте потрійний ланцюжок:->(s){s=~/^$|^\d|\W/?0:s=~/^_/?0.5:1}
Значення чорнила

@KevinLau Правда - я вже додав чергову відповідь у рубіні (хоча це теж не чудово)
Flambino

0

Луа, 82 - 10% = 73,8

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

Випробування:

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

Я думаю, ви можете використовувати STDIN, щоб з'їсти принаймні 10 байт.
Лина монахиня

0

Луа, 68 * .9 = 61,2 байт

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

Бере аргументи в командному рядку

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.