Bu bir sayı mı?


17

Prelude:

Test senaryoları hazırlamak istedim, bu yüzden onları kolay bir şey üzerinde deneyeceğim.

Meydan okuma:

Herhangi bir (dize) girişi (görünür ASCII aralığında) alın ve bir sayı olup olmadığını bulun ve değerlendirmek için kullanılabilecek bir şey çıkarın.

Kurallar:

  • Bir sayı yalnızca karakterleri içerecektir -0123456789,.
  • Yanıtlar yalnızca -1000000000 ve 1000000000 (özel) arasındaki sayıları tanımak için gereklidir, ancak keyfi olarak büyük sayıları tanıyabilir.
  • Tam bir program veya işlev yazabilirsiniz.
  • Bir sayı varsa, onu ayırt etmek ve çıktıdaki açıklamayı belgelemek için kullanılabilecek her şeyi döndürün (ör. My program outputs T if a number, F if not.).
  • Giriş, ASCII aralığında herhangi bir miktarda karakter veya boş olacaktır (boşsa, sayı değilse çıktı olarak verdiğiniz her şeyi döndürür).
  • Sayılar ondalık nokta içerebilir (ör. 3.14). Eğer öyleyse, ondalık noktadan önce en az bir basamak ve ondan sonra en az bir basamak olmalıdır.
  • Sayıların başında veya sonunda sıfır olabilir (ör. 000001.00000).
  • Bir sayının tamsayı kısmı okunabilirlik için virgülle üç basamaklı parçalara bölünebilir (ör. 1,000.23456). Bu durumda onlar sol sağdan Her üç basamağı bölünmüş olmalıdır özellikleri (ör. 1,234,567, 10,000.202, 123,234.00, 0,123.293).
  • Negatif sayılar bir satır başı ile gösterilir -(ör. -1.23). +Pozitif bir sayıyı göstermeye yol açan bir karaktere izin verilmez ve hatalı çıktıyla sonuçlanmalıdır.
  • İstisnalar geçerli ve fark edilebilir çıktı olarak DEĞİLDİR (çıktıları standart çıkış akışına geçirebildikleri durumlar hariç (ör. Exception on line N [...], Dize standart çıkış akışına konulursa bir sayı / sayı olmayan sayı için çıkış olarak eklenebilir).

Test senaryoları:

( My program outputs T if a number, F if not.sürümü varsayarak )

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]

, en az karakter kazanır.


Girişin her zaman ASCII olduğunu varsayabilir miyiz?
Brad Gilbert b2gills

@ BradGilbertb2gills, evet.
n4melyh4xor

Eğer -123uygunsa, +456ya iyi ya da kötü. Yoksa +partinin dışında mı kalıyor?
chux - Monica'yı

@chux, parti treni oraya varmadan önce ayrıldı. Bir dahaki sefere iyi şanslar, +.
n4melyh4xor

2
Kullanıcılar yorumlarda açıklama istediğinde, soruyu düzenlemeniz gerekir. Spesifikasyonu bilmek için yorumları okumak asla gerekli olmamalıdır. Cevapları ve bazı test senaryolarını içerecek şekilde düzenledim.
Peter Taylor

Yanıtlar:


10

Retina , 28 29 31 40 34 bayt

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

1Doğruysa çıktılar , 0aksi takdirde. Anladığım kadarıyla, bu durumda Retina, normal ifadenin girişteki eşleşme sayısını çıkarır.

Çevrimiçi deneyin!

Test odası

Düzenlemeler

  • "Ondalık basamaktan sonra basamak olmalı" kuralına uyulması düzeltildi
  • "Negatifleri ele alma" kurallarına uyma sorunu giderildi
  • İsteğe bağlı virgül ayırıcılarla uyumlu olması düzeltildi
  • @MartinEnder tarafından not edildiği gibi binlerce ayırıcıdaki hata düzeltildi
  • Koşullu taramayı kaldırarak golf oynamak

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 Düzeltildi! Ayrıca, Retina'daki bayrakları ( mve için bayraklar söyleyin g) nasıl belirtirsiniz ?
Kritixi Lithos

Normal `ifadenin önüne a koyun ve değiştiriciler bunun önüne geçin, örn m`^.$. g.NET'te mevcut değil, eşleşmeler varsayılan olarak geneldir.
Martin Ender

3

JavaScript, 46 49 bayt

Bu, Retina cevabımın doğrudan bir limanı. JS'yi kullanmamın tek nedeni, aşağıdaki Snack Snippet'ini kullanarak normal ifadeyi test etmenin kolay bir yolu olması.

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>


Bazı kurallar (virgül kuralı gibi) olmasaydı isNaN(+prompt()), 16 karakter için yapılabilirdi. Sanırım hayat böyle
Matheus Avellar

2

Perl 6 , 42 bayt

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

Dene

Expanded:

{  # 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 bayt

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

Yerleşik virgüllerle başa çıkamaz ve bilimsel gösterimi kabul eder; bu yüzden regex yolunda yürümek zorunda kaldım. <?=is_numeric($argv[1]);24 bayt olurdu.


0

bash / Unix araçları, 64 bayt

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

Bunu bir dosya olarak kaydedin ve ilk bağımsız değişken olarak test edilecek dizeyi komuta iletin.

Çıktı sayı olmayan için 0, sayı için 1'dir.

Stdin'den girişi kabul etmek istiyorsanız ve girişin sadece bir satırdan oluştuğunu garanti ediyorsanız, sonunda <<< "$ 1" i kaldırarak 57 bayt elde edebilirsiniz .

Kodun kendisi için, egrep için -c seçeneği eşleşen satırların sayısını (0 veya 1 olacaktır) sayar.



0

C89, 195 bayt

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;}

Ungolfed:

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;
}

0

Python 2, 79 bayt

Regex çözümü

import re
lambda s:[s]==re.findall('-?(?:\d{1,3}(?:,\d{3}\d+)(?:\.?\d+)?',s)


-?                                          | Starts with 0-1 dashes
  (?:\d{1,3}(?:,\d{3})+                     | Have 1-3 digits and 1+ (comma followed by 3 digits)
                       |\d+)                | or 1+ digits
                            (?:\.?\d+)?     | Ends with dot and 1+ digits or nothing

Çevrimiçi deneyin


0

c #, 75 bayt

bool t(string n){double v;return double.TryParse(n.Replace(",",""),out v);}
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.