Це число?


17

Прелюдія:

Мені хотілося навчитись робити тестові справи, тож я спробую їх на чомусь легкому.

Виклик:

Візьміть будь-який заданий (рядковий) вхід (у видимому діапазоні ASCII) і виведіть, якщо це число, і виведіть щось, що може бути використане для оцінки.

Правила:

  • Число містить лише символи -0123456789,.
  • Відповіді потрібні лише для розпізнавання чисел від -1000000000 до 1000000000 (виключно), але можуть розпізнавати довільно великі числа.
  • Ви можете написати повну програму або функцію.
  • Якщо число, поверніть все, що могло б бути використане для його розпізнавання, і задокументуйте результат у описі (наприклад My program outputs T if a number, F if not.).
  • Введеним буде будь-яка кількість символів у діапазоні ASCII або порожній (якщо порожній повертає все, що ви виведете, якщо не число).
  • Числа можуть включати десяткову точку (наприклад 3.14). Якщо це так, вони повинні мати принаймні одну цифру перед десятковою комою і хоча б одну після неї.
  • Числа можуть мати провідні або кінцеві нулі (наприклад 000001.00000).
  • Цілу частину числа можна розділити для читабельності на шматки трьох цифр з комами (наприклад 1,000.23456). У цьому випадку вони повинні бути розділені кожні три цифри справа наліво (напр. 1,234,567, 10,000.202, 123,234.00, 0,123.293).
  • Номери негативів позначаються ведучим -(наприклад -1.23). Показник, +який вказує на позитивне число, не дозволений, і це повинно призвести до помилкового виходу.
  • Винятки НЕ зараховуються як дійсний та помітний вихід (за винятком випадків, коли вони можуть передавати виходи в стандартний вихідний потік (наприклад, Exception on line N [...]можна вводити як вихід для числа / nonnumber, якщо рядок буде розміщено у стандартному вихідному потоці).

Тестові приклади:

(припускаючи My program outputs T if a number, F if not.версію)

123 -> T [on integer]
-123 -> T [negative numbers need to be handled]
0 -> T [on zero]
123.456 -> T [on floating point]
123,456.789 -> T [on evenly divided by 3 digits with comas]
123456789 -> T [thousand separators are not required]
0000001.00000 -> T [on leading/trailing zeros]
00.00 -> T [on zero and leading/trailing zeros]
999999999.9999999999999999999999999999999999999999999999999999 -> T [on close to the maximum value]
-999999999.9999999999999999999999999999999999999999999999999999 -> T [on close to the minimum value]
 -> F [on empty]
lolz -> F [on non-number value]
n4melyh4xor -> F [on non-number with digits]
  1.2 -> F [on space-padded]
9.3 1.3 -> F [on anyhow separated multiple numbers]
1e5 -> F [no scientific notation]
50cl05e.buty3ts0f4r -> F [on input with letters obscuring the number]
1,2,3,4.5678 -> F [on badly readability-divided number]
1,234.5,678 -> F [on readability-divided floating point part]
.234 -> F [on no leading zero]
+1 -> F [no leading + sign]
1.234.3 -> F [only one decimal point]
12345,678 -> F [on separator stopping mid-way]

, найменше символів - переможець.


Чи можемо ми вважати, що вхід завжди ASCII?
Бред Гілберт b2gills

@ BradGilbertb2gills, так.
n4melyh4xor

Якщо -123все в порядку, то що +456-> добре чи погано. Або +залишається поза партією?
chux

@chux, поїзд партії виїхав до того, як + туди потрапив. Пощастить наступного разу, +.
n4melyh4xor

2
Коли люди запитують роз'яснення в коментарях, вам слід відредагувати питання. Ніколи не слід читати коментарі, щоб знати специфікацію. Я редагував, щоб включати відповіді та деякі тестові приклади.
Пітер Тейлор

Відповіді:


10

Сітківка , 28 29 31 40 34 байт

^-?\d{1,3}((,\d{3})*|\d*)(\.\d+)?$

Виходи, 1якщо непросто, 0інакше. Наскільки я розумію, у цьому випадку Retina видає кількість збігів, які має регулярний вираз на вході.

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

Тестовий сюїт

Правки

  • Виправлено, щоб відповідати правилу "повинні бути цифри після десяткового знака"
  • Виправлено для дотримання правил "обробляти негативи"
  • Виправлено для дотримання додаткових роздільників комах
  • Виправлена ​​помилка з тисячами роздільників, як зазначає @MartinEnder
  • Гольф, видаливши умовний лукахед

RegExplanation

^-?\d{1,3}((,\d{3})*|\d*)(\.\d+)?$
^                                $  This marks the start and end of regex
 -?                                 Optional hyphen for negative number
   \d{1,3}                          Matches between 1 and 3 digits
          (             )           Capturing group
           (,\d{3})*                 Matches at least zero of comma and three numbers (in the case of separators)
                    |                OR
                     \d*             Matches at least zero digits (in the case of no separators)
                        (\.\d+)?    Matches an optional . and at least one digit (for decimal numbers)

@MartinEnder Виправлено! Крім того, як вказати прапори (скажімо, прапори для mі g) у Retina?
Kritixi Lithos

Поставте a `перед виразкою, а потім модифікатори йдуть перед цим, наприклад m`^.$. gне існує в .NET, збіги за замовчуванням є глобальними.
Мартін Ендер

3

JavaScript, 46 49 байт

Це прямий порт моєї відповіді на Retina. Єдина причина, по якій я використовував JS, - це те, що є простий спосіб протестувати регулярний вираз, використовуючи Snap Snippet нижче

f=s=>/^-?\d{1,3}((,\d{3})*|\d*)(\.\d+)?$/.test(s)

f=s=>/^-?\d{1,3}((,\d{3})*|\d*)(\.\d+)?$/.test(s)
<input oninput=p.innerText=f(value)><p id=p></p>


Якби не деякі правила (наприклад, правило з комою), можна було просто зробити isNaN(+prompt())16 символів. Я думаю, таке життя
Матей Авельяр

2

Перл 6 , 42 байти

{?/^\-?[\d**1..3[\,\d**3]+|\d+][\.\d+]?$/}

Спробуй це

Розширено:

{  # bare block lambda with implicit parameter 「$_」

  ? # turn the following into a Bool result

  /  # match implicitly against 「$_」

    ^                 # beginning of string

    \- ?              # optional leading 「-」

    [

      \d ** 1..3      # 1 to 3 digits
      [
        \,            # comma
        \d ** 3       # three digits
      ]+              # repeat at least once

    |                 # or

      \d+             # at least one digit

    ]

    [ \. \d+ ]?       # 「.」 followed by at least one digit optionally

    $  # end of string

  /
}

1

PHP, 62 байти

<?=preg_match("#^-?(\d+|\d{1,3}(,\d{3})*)(\.\d+)?$",$argv[1]);

Вбудований не може поводитися з комами, і він приймає наукові позначення; тому мені довелося піти регексом. <?=is_numeric($argv[1]);було б 24 байти.


0

інструменти bash / Unix, 64 байти

egrep -c '^-?([0-9]+|[0-9]{1,3}(,[0-9]{3})+)(\.[0-9]+)?$'<<<"$1"

Збережіть це як файл і передайте команду рядок, який потрібно перевірити, як перший аргумент.

Вихід 0 для не числа, 1 для числа.

Якщо ви готові прийняти вхід від stdin і якщо ви можете гарантувати, що вхід складається лише з одного рядка, ви можете видалити <<< "$ 1" наприкінці, в результаті чого вийде 57 байт .

Що стосується самого коду, то опція -c для перерізування підраховує кількість відповідних рядків (яка буде або 0, або 1).


0

Pyth, 25 символів

:zCiCM"૧򡊪񛨮򶟉񠫊򆻛񓰚祥񯯏󪬡򢝉񁘍񲲂쪤"^T6

Компреси регулярний вираз Kritixi LITHOS ' .

Спробуйте в Інтернеті. Використовує символи Unicode поза базовою багатомовною площиною, з якою TIO, мабуть, не може впоратися? Це маленьке додаток повідомляє про неправильний розмір для рядка. Цей лічильник символів / байтів отримує це правильно.


0

C89, 195 байт

b,d,c,i;f(char*s){b=*s;for(d=c=i=0;i++,*(s++),d+=*s=='.',c+=*s==',',b=c?i&(i%4!=3)&*s==','?0:b:b;)if(*s==45&!i);else if((*s==32)|(*s==46)|*s==43|!isdigit(*s)&*s!=46&*s!=44)||!(d-1))b=0;return b;}

Безумовно:

bool is_base10_number (const char* const str) {

  if(!str[0])return false;

  size_t
    dpts = 0,
    cmas = 0;

  for (size_t i = 0; i < strlen(str); i++) {

    if ((str[i] == '-') && (!i)){
      continue;
    }

    if (
      (str[i] == ' ')
      || (str[0] == '.')
      || (str[0] == '+')
      ||
      (
        (!isdigit(str[i]))
        && (str[i] != '.')
        && (str[i] != ',')
      )
    ) {
      return false;
    }

    dpts += str[i] == '.';
    cmas += str[i] == ',';

    if (cmas) {
      if (i & ((i % 4) != 3) & str[i] == ',') {
        return false;
      }
    }

  }

  if (dpts > 1) { return false; }

  return true;
}


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