これは数字ですか?


17

前奏曲:

テストケースの作成を訓練したかったので、簡単なもので試してみます。

チャレンジ:

任意の(文字列)入力(ASCIIの範囲内)を取得し、それが数値であるかどうかを推測し、評価に使用できるものを出力します。

ルール:

  • 数字には文字のみが含まれます -0123456789,.
  • 回答は、-1000000000〜1000000000(排他的)の間の数字を認識するためにのみ必要ですが、任意の大きな数字を認識する場合があります。
  • 完全なプログラムまたは関数を作成できます。
  • 数値の場合、識別に使用できるものをすべて返し、説明に出力を文書化します(例:)My program outputs T if a number, F if not.
  • 入力は、ASCII範囲内の任意の量の文字または空です(空の場合、数値でない場合は出力するものを返します)。
  • 数字には小数点を含めることができます(例:)3.14。その場合、小数点の前に少なくとも1桁、その後に少なくとも1桁の数字が必要です。
  • 数値の先頭または末尾にゼロを付けることができます(例:)000001.00000
  • 数値の整数部分は、読みやすくするために、カンマ付きの3桁のチャンクに分割できます(例:)1,000.23456。この場合、それらは、右から左に3桁ごとに分割する必要があります(例:1,234,56710,000.202123,234.000,123.293)。
  • 負の数は、先頭-(例-1.23)で示されます。+正の数を示すためのリードは許可されず、偽の出力になるはずです。
  • 例外は、有効で識別可能な出力としてカウントされません(標準出力ストリームに出力を渡すことができる場合を除きます(Exception on line N [...]たとえば、文字列が標準出力ストリームに出力される場合、数値/非数値の出力として入力できます)。

テストケース:

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 16

@ BradGilbertb2gills、はい。
n4melyh4xor 16

よければ-123、どうですか+456->良いか悪いか。それともれる+パーティーから取り残さ?
chux -復活モニカ

@chux、パーティ列車は+が到着する前に出発しました。次回は幸運を祈ります、+。
n4melyh4xor 16

2
コメントで説明を求める場合は、質問を編集する必要があります。仕様を知るためにコメントを読む必要はありません。回答といくつかのテストケースを含めるように編集しました。
ピーターテイラー

回答:


10

網膜28 29 31 40 34バイト

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

1真実であれば出力、0そうでなければ出力。私の知る限り、この場合、Retinaは正規表現が入力で持つ一致の数を出力します。

オンラインでお試しください!

テストスイート

編集

  • 「小数点以下に数字が必要」ルールに準拠するように修正
  • 「ネガ処理」ルールに準拠するように修正
  • オプションのカンマ区切り記号に準拠するように修正
  • @MartinEnderで指摘されている数千のセパレーターのバグを修正
  • 条件付き先読みを削除してゴルフ

再説明

^-?\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修正!また、Retinaでフラグを指定するには(たとえば、mおよびのフラグg)?
Kritixi Lithos

a `を正規表現の前に置くと、修飾子がその前に移動します(例:)m`^.$g.NETには存在しません。デフォルトでは一致はグローバルです。
マーティンエンダー

3

JavaScript、46 49バイト

これは、Retinaの回答の直接の移植版です。私がJSを使用した唯一の理由は、以下のスナックスニペットを使用して正規表現をテストする簡単な方法があるためです

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文字で対応できます。このような人生は、私は考えます
マテウスAvellar

2

Perl 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行のみで構成されていることを保証できる場合は、末尾の<<< "$ 1"を削除して57バイトにすることができます

コード自体に関しては、egrepの-cオプションは、一致する行の数(0または1)をカウントします。



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

0

Python 2、79バイト

正規表現ソリューション

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

オンラインで試す


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.