数字の文字列を単語から整数に変換します


19

先行ゼロを無視して、数字を単語として含む文字列を整数に変換します。

  • "four two"-> 42
  • "zero zero zero one"-> 1

仮定

提出は次のことを想定できます:

  1. 入力文字列は、スペースで区切られた数字の単語で構成されます。
  2. すべての単語は有効で(「zero」..「nine」の範囲内)、小文字です。空の入力の動作は未定義です。
  3. 入力文字列は、常に範囲内の符号なしの数値を表しint、空の文字列ではありません。

得点

回答はバイト単位でスコアリングされ、バイト数は少ない方が良いです。


3
サイトへようこそ。ここで不足している質問から通常期待することがいくつかあります。最も重要なのは、すべての課題に必要な客観的なスコアリング基準です。
小麦ウィザード

3
それ以外に、この質問は仕様が非常にまばらです。曖昧さなく提出に必要なものを正確に指定してください。1つの文と例は、課題に対する明確な基準に達していないだけです。
小麦ウィザード

3
既に述べたことに加えて、ユーザーがメインに投稿する前にチャレンジを投稿できるサンドボックスがあります。そうすることで、投稿する際に見逃す情報が少なくなります。サイト上の他の最近の投稿をかなり前向きに見ると、あなたの質問と解決策の両方がここでやっていることとまったく一致していないことがわかると思います。
FryAmTheEggman

3
物足りなさの危険があるので、私range "zero".."nine"は完全に指定されていないことを指摘したいと思います。
21:22の無関係な文字列

4
迷惑なことに、組み込み関数Interpreter@"SemanticNumber"はMathematicaでまさにこれを行いzero zero ます。ただし、で始まる文字列では失敗します。
グレッグマーティン

回答:


22

PHP、74バイト

foreach(explode(' ',$argn)as$w)$n.='793251_8640'[crc32($w)%20%11];echo+$n;

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

既存の回答をコピーしないソリューションを取得しようとしました。各ワードに対して32ビット長の巡回冗長チェックサム多項式(crc32)を取得し、それに対してmod 20とmod 11を実行して、各桁に対して0から10(欠損値6)の一意の値を混合します。次に、その一意の値を使用して、実際の数字を見つけます。

| Word  | CRC32      | %20 | %11 | Equivalent digit |
|-------|------------|-----|-----|------------------|
| zero  | 2883514770 | 10  | 10  | 0                |
| one   | 2053932785 | 5   | 5   | 1                |
| two   | 298486374  | 14  | 3   | 2                |
| three | 1187371253 | 13  | 2   | 3                |
| four  | 2428593789 | 9   | 9   | 4                |
| five  | 1018350795 | 15  | 4   | 5                |
| six   | 1125590779 | 19  | 8   | 6                |
| seven | 2522131820 | 0   | 0   | 7                |
| eight | 1711947398 | 18  | 7   | 8                |
| nine  | 2065529981 | 1   | 1   | 9                |

別の74バイトCRC32の代替手段%493%10オンラインで試してみてください!

別の74バイトCRC32の代替手段%2326%11オンラインで試してみてください!


PHP、74バイト

foreach(explode(' ',$argn)as$w)$n.=strpos(d07bfe386c,md5($w)[21]);echo+$n;

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

同じ長さの別の選択肢md5は、単語の22番目の文字(各単語に一意の値を与える文字のみ)を取得し、その文字を使用して数字にマッピングします。


これはクールな答えです
フアンセバスチャンロザノ



6

ゼリー 19  17バイト

Ḳµ7ị“*;nÄƲ]³Ṙ»i)Ḍ

整数を生成する文字のリストを受け入れる単項リンク。

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

私のPython 2の答えのかなりの部分です。


ḲŒ¿€i@€“©¥q£½¤MÆÑ‘Ḍ

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

おそらくもっと短い方法ありますが、これは最初に頭に浮かんだ方法です。


検出されないため、enklact文字列からゼロを削除して減分を回避します。
無関係な文字列

1
ああ、同じ方法を使ったと思うよ。
ジョナサンアラン

5

Pythonの31079177、90のバイト

Sriotchilism O'Zaicによる-16バイト

先行ゼロを削除するには+13バイト

lambda s:int(''.join(map(lambda w:str('zeontwthfofisiseeini'.index(w[:2])//2),s.split())))

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



良いですね!そう
すれば

1
チャレンジの更新では、先行ゼロが含まれるため、これはもはや有効ではありません。:(
小麦ウィザード


1
@movatica修正は正しくありません。このlstripメソッドは、引数として指定された文字列内のすべての文字を削除します。そのため、「e」が削除されると、「eight two」は「ight two」になります。また、「ゼロゼロゼロ」は「0」を出力し、エラーを出力しません。
NemPlayer



3

05AB1E18 16 バイト

#ε6è}.•ƒ/ÿßÇf•Åβ

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

説明:

#                 # Split the (implicit) input-string on spaces
 ε  }             # Map each string to:
  6è              #  Get the character at 0-based index 6 (with automatic wraparound)
     .•ƒ/ÿßÇf    # Push compressed string "rothuvsein"
              Åβ  # Convert the characters from custom base-"rothuvsein" to an integer
                  # (after which the top of the stack is output implicitly as result)

この05AB1E鉱山の先端を参照してください(セクション圧縮文字列の辞書の一部ではないにどのように?理由を理解すること.•ƒ/ÿßÇf•です"rothuvsein"




3

網膜0.8.246の 45バイト

\w+
¶$&$&$&
%7=T`r\ot\huvs\ein`d`.
\D

^0+\B

オンラインでお試しください!リンクにはテストケースが含まれます。説明:

\w+
¶$&$&$&

各単語をそれぞれの行に入れて、3つ複製します。

%7=T`r\ot\huvs\ein`d`.

@UnrelatedStringの文字列を使用して、各行の7番目の文字を音訳します。

\D

残りのすべての数字以外の文字を削除します。

^0+\B

先行ゼロを削除します(ただし、少なくとも1桁は残します)。

以前の46バイトの従来のソリューション:

T`z\wuxg`E
on
1
th
3
fi
5
se
7
ni
9
\D

^0+\B

オンラインでお試しください!リンクにはテストケースが含まれます。説明:

T`z\wuxg`E

言葉はzerotwofoursixおよびeight一意の文字が含まれていますzwuxg。それらを偶数に音訳します。

on
1
th
3
fi
5
se
7
ni
9

奇数の場合、各単語の最初の2文字を個別に一致させます。

\D

残りのすべての数字以外の文字を削除します。

^0+\B

先行ゼロを削除します(ただし、少なくとも1桁は残します)。


2

ゼリー20 18 17バイト

Ḳ7ị“*;nÄƲ]³Ṙ»iƲ€Ḍ

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

- "rothuvsein"の実行からuser202729の文字列コンプレッサーまで-2バイト

Jonathan Allanのゼロフリーのenklact文字列を盗んで、わずかに異なる構造のプログラムに入れてから-1バイト。

Ḳ                    Split the input on spaces,
              Ʋ€     for each word
             i       find the 1-based index (defaulting to 0)
   “*;nÄƲ]³Ṙ»        in "othuvsein"
 7ị                  of the element at modular index 7,
                Ḍ    and convert from decimal digits to integer.


2

Japt、13 バイト

¸mg6 ì`Ψuv 

それを試してみてください

他の皆が私に同じ考えを打ち負かしたように見えます-圧縮のために最適な文字列をブルートフォースするスクリプトを書く手間を省くことができました、それを見つけるために、インデックスまで1,000,000(それは早く、私はまだカフェイン!)、「rothuvsein」のみが可能な文字列です!

¸mg6 ì`...     :Implicit input of string
¸              :Split on spaces
 m             :Map
  g6           :  Character at index 6 (0-based, with wrapping)
     ì         :Convert from digit array in base
      `...     :  Compressed string "rothuvsein"

圧縮された文字列は、コードポイントに文字が含まれ206168117118160136


1
...本当に1000000まで試してみましたか?桁名の長さのlcmは60であるため、それを超えることはできません(60は0、61対1などに相当します)。
グリミー

1
@Grimy、早かった、まだカフェインを持っていなかった!すべての可能性を生成するために私が書いたスクリプトに100万個を差し込むことは、他の数と同じくらい簡単で、LCMで数学を行うことを節約しました。
シャギー


2

T-SQL、110バイト

SELECT 0+STRING_AGG(CHARINDEX(LEFT(value,2),'_ontwthfofisiseeini')/2,'')
FROM STRING_SPLIT((SELECT*FROM i),' ')

改行は読みやすくするためのものです。

説明:

  1. STRING_SPLIT 入力文字列を取得し、スペースで区切ります
  2. CHARINDEX最初の2文字を取得し、文字列の(1から始まる)位置を返します'_ontwthfofisiseeini''ze'ゼロは文字列に含まれず、「not found」に対して0を返します。アンダースコアにより、2の倍数のみが取得されます。
  3. 2で割って最終的な数字を取得します
  4. STRING_AGG 数字を区切りなしで元に戻します
  5. 0+暗黙的にINTに変換し、先行ゼロを削除します。1*また動作します。

2

x86マシンコード、46バイト

Hexdump:

57 53 33 c0 33 ff f6 01 0f 75 15 6a 0a 5b 99 f7
f3 6b ff 0a 03 fa 33 c0 38 01 75 0f 97 5b 5f c3
69 c0 26 2b aa 6e 32 01 c1 e8 02 41 eb d8

それはだfastcall機能-の文字列へのポインタを受け取りecx、そして中に結果を返します。eax

ハッシュ関数はマジック番号を乗算し、入力バイトで1856645926a XORを実行し、2ビット右にシフトします。

noclobberレジスタ(ediおよびebx)の保存と復元には4バイトかかりましたが、これを実装するより効率的な方法は見つかりませんでした。定数10を保存するのebxは特に面倒でした!

対応するコードバイトでの逆アセンブリ:

57                   push        edi  ; edi = result
53                   push        ebx  ; we use ebx to store the constant 10
33 C0                xor         eax,eax  
33 FF                xor         edi,edi  
    myloop:
F6 01 0F             test        byte ptr [ecx],0Fh  ; check for end of word
75 15                jne         myhash
6A 0A                push        0Ah  
5B                   pop         ebx  
99                   cdq              ; prepare 64-bit dividend in edx:eax
F7 F3                div         eax,ebx  ; find the remainder of division by 10
6B FF 0A             imul        edi,edi,0Ah
03 FA                add         edi,edx  ; update the result
33 C0                xor         eax,eax  ; reset the hash temporary variable
38 01                cmp         byte ptr [ecx],al  ; check for end of input (here al=0)
75 0F                jne         mycontinue
97                   xchg        eax,edi  ; set the return register
5B                   pop         ebx  ; restore registers
5F                   pop         edi  ; restore registers
C3                   ret  
    myhash:
69 C0 26 2B AA 6E    imul        eax,eax,6EAA2B26h  ; hashing...
32 01                xor         al,byte ptr [ecx]  ; hashing...
C1 E8 02             shr         eax,2  ; hashing...
    mycontinue:
41                   inc         ecx  ; next input byte
EB D8                jmp         myloop

同等のCコード:

int doit(const char* s)
{
    int result = 0;
    unsigned temp = 0;
    while (true)
    {
        int c = *s++;
        if ((c & 15) == 0)
        {
            temp %= 10;
            result = result * 10 + temp;
            temp = 0;
            if (c == 0)
                break;
            else
                continue;
        }
        temp *= 1856645926;
        temp ^= c;
        temp >>= 2;
    }
    return result;
}

どのようにしてマジックナンバーを見つけましたか?
線香花火

Cコードを使用して検索を行いました。32ビットのすべての数値とすべてのシフトを試しました。そこだけいくつかの可能性があります-コードが2000000000.までの範囲でのみ1を発見した
anatolyg

ediの代わりにedxを使用して(idxの前にedxをプッシュし、その後にeaxをポップし、ebxでimulし、edxにeaxを追加します)1バイトを節約できます。
ピーターフェリー



1

、19バイト

I⍘⭆⪪S §ι⁶rothuvsein

オンラインでお試しください!リンクは、コードの詳細バージョンです。@KevinCruijssenの05AB1E回答のポート。説明:

    S               Input string
   ⪪                Split on spaces
  ⭆                 Map over words and join
       ι            Current word
      §             Cyclically indexed
        ⁶           Literal `6`
 ⍘       rothuvsein Custom base conversion
I                   Cast to string for implicit print

1

PowerShell、48バイト

+-join($args|%{'rothuvsein'.indexof(($_*3)[6])})

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

rothuvseinジョナサンアランのおかげで、他の人と同じトリックを使用しています。TIOで個別のコマンドライン引数として現れるスプラッティングを介して入力引数を期待します。


1

Kotlin、83バイト

fun String.d()=split(' ').fold(""){a,b->a+"rothuvsein".indexOf((b+b+b)[6])}.toInt()

ロングをサポートしたい場合は+1バイト toLong()

他と同じrothuvseinトリック、kotlinのnice toInt()とのおかげで貴重なバイトを節約できますfold()。しかし、さらにバイトを削ることができるという感覚を揺るがすことはできません...



1

Windowsバッチ、169バイト

@setlocal enabledelayedexpansion
@set z=zeontwthfofisiseeini
:a
@set b=%1
@for /l %%c in (0,2,18)do @if "!b:~0,2!"=="!z:~%%c,2!" set/aa=a*10+%%c/2&shift&goto a
@echo %a%


0

VBA、160バイト

Function e(s)
s = Split(s, " ")
For i = LBound(s) To UBound(s)
s(i) = Int((InStr("ontwthfofisiseeini", Left(s(i), 2)) + 1) / 2)
Next
e = Val(Join(s, ""))
End Function

文字列の最初の2文字と一致します。ゼロは除外されます。


0

ベーコン83 72バイト

文字列がw $で提供されると仮定すると、このコードは各単語の一意の最初の2文字に基づく正規表現を使用して「zeontwthfofisiseeini」でインデックスを検索します。インデックスは2で除算され、正しい結果が得られます。

FOR x$ IN w$:r=r*10+REGEX("zeontwthfofisiseeini",LEFT$(x$,2))/2:NEXT:?r
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.