文言電卓


14

英語の数字計算機の単純なバージョン

仕事

入力として文字列を受け取り、式の結果を出力するプログラムを作成します。

ルール

入力文字列は、数字ではなく言葉で表現されます。

括弧はありません。

計算の順序は、除算、乗算、減算、加算の順になります。

同じ操作の場合、左から右に計算する必要があります。

すべての入力番号は-999〜999の整数になります(両方を含む)。

出力は任意の範囲の整数になります。

除算は常に完全に割り切れ、ゼロは分母にはなりません。

入力の大文字と小文字の制限はオプションです。入力の有効性を確認する必要はありません。

数値形式

0 to 20 -> zero,one,two...nineteen,twenty
21 to 99 -> twenty one,twenty two.....ninety eight,ninety nine
100 to 999 -> one hundred, one hundred one, one hundred two...one hundred ten....two hundred fifty....nine hundred ninety eight,nine hundred ninety nine

負の数の場合:minusその正の同等物に追加

操作形式

Addition: one plus two
Subtraction: one minus two
Multiplication: one time two #Note that for one on the left of multiplication, it is one time and not times.
                two times one hundred
Division: forty divided by two

例:

o/p <- input

20     four times five
35     twenty plus fifteen
70     fifty plus five times four
-90    minus one time ninety
25     twenty one minus minus four
45     ninety divided by two
700    one time seven hundred 
555    one hundred eleven times two plus three hundred thirty three
99     one hundred plus minus one
45     forty five plus two hundred times zero
 4     four
-3     three minus three minus three

これはコードゴルフなので、最短のコードが勝ちます


1
重複しますか?-それはそのように考えられるほど近いと思います。
キリルL.

2
本当に近いです。しかし、これはより適切に指定され、より合理的な制限があると思います。
アーナウルド

1
@Arnauldでは、これを開いたままにしますが、他の人が違うと思う場合は、重複としてマークします。
ヴェダントカンドー

15
と言うone times twotime通常使用していますか?
ジョーキング

2
私は、あなたが「1時間のものだと思い 700」?
ouflak

回答:


18

JavaScript(ES6)、257 252 249 235バイト

@Shaggyのおかげで3バイト節約

s=>eval(s.split` `.map(w=>(i='zeonwohrr44fx3n5t54nn3leel8tou7fn7n98etetwthfofisiseeinihuplmitidiby'.match(/../g).findIndex(x=>~(w+w.length+w).search(x)))>28?n+' '+'+-*/ '[n='',i-29]:(n=+n+(i<28?i<20?i:i*10-180:n*99),''),n='').join``+n)

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

どうやって?

WLW+L+W

数字

 index | word              | word + length + word         | key substring
-------+-------------------+------------------------------+---------------
    0  | "zero"            | "zero4zero"                  | "ze"
    1  | "one"             | "one3one"                    | "on"
    2  | "two"             | "two3two"                    | "wo"
    3  | "three"           | "three5three"                | "hr"
    4  | "four"            | "four4four"                  | "r4"
    5  | "five"            | "five4five"                  | "4f"
    6  | "six"             | "six3six"                    | "x3"
    7  | "seven"           | "seven5seven"                | "n5"
    8  | "eight"           | "eight5eight"                | "t5"
    9  | "nine"            | "nine4nine"                  | "4n"
   10  | "ten"             | "ten3ten"                    | "n3"
   11  | "eleven"          | "eleven6eleven"              | "le"
   12  | "twelve"          | "twelve6twelve"              | "el"
   13  | "thirteen"        | "thirteen8thirteen"          | "8t"
   14  | "fourteen"        | "fourteen8fourteen"          | "ou"
   15  | "fifteen"         | "fifteen7fifteen"            | "7f"
   16  | "sixteen"         | "sixteen7sixteen"            | "n7"
   17  | "seventeen"       | "seventeen9seventeen"        | "n9"
   18  | "eighteen"        | "eighteen8eighteen"          | "8e"
   19  | "nineteen"        | "nineteen8nineteen"          | "te"
   20  | "twenty"          | "twenty6twenty"              | "tw"
   21  | "thirty"          | "thirty6thirty"              | "th"
   22  | "forty"           | "forty5forty"                | "fo"
   23  | "fifty"           | "fifty5fifty"                | "fi"
   24  | "sixty"           | "sixty5sixty"                | "si"
   25  | "seventy"         | "seventy7seventy"            | "se"
   26  | "eighty"          | "eighty6eighty"              | "ei"
   27  | "ninety"          | "ninety6ninety"              | "ni"
   28  | "hundred"         | "hundred7hundred"            | "hu"

オペレーター

 index | word              | word + length + word         | key substring
-------+-------------------+------------------------------+---------------
   29  | "plus"            | "plus4plus"                  | "pl"
   30  | "minus"           | "minus5minus"                | "mi"
   31  | "times" or "time" | "times5times" or "time4time" | "ti"
   32  | "divided"         | "divided7divided"            | "di"
   33  | "by"              | "by2by"                      | "by"

解釈

n

i > 28 ?                  // if the word is an operator:
  n +                     //   append n (which is either an empty string or a number)
  ' ' +                   //   append a space
  '+-*/ '[n = '', i - 29] //   reset n to an empty string and append the operator
                          //   the useless keyword 'by' is translated into a harmless space
: (                       // else:
    n =                   //   update n:
      +n + (              //     force the coercion of the current value of n to a number
        i < 28 ?          //     if the word is not 'hundred':
          i < 20 ?        //       if the value of the word is less than 'twenty':
            i             //         add i
          :               //       else:
            i * 10 - 180  //         add i * 10 - 180 (e.g. 'fifty' -> 23 * 10 - 180 = 50)
        :                 //     else:
          n * 99          //       multiply n by 100 by adding 99 * n to itself
      ),                  //
    ''                    //   remove this word from the original string
  )                       //

11

Perl 6の170の139 129 128 124 122バイト

nwellnhofのおかげで-13バイト!

{S:g/(<:N>+)+%\s/({'+'X$0})/.EVAL}o{S:g/" ҈"/00/}o{TR"⁢ʼn؊⟠"*/൰ "}o*.words>>.&{chr first *.uniname.comb(.uc),1..*}

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

unival再び救助に!これは(現在)ゴルフのような言語を打ち負かすこと05AB1Eです!

説明:

*.words     # Split by word boundaries (in this case spaces)
       >>.{                            }  # Map each word to
           chr first             ,1..*    # The first character where:
                     *.uniname      # The unicode name of that character
                                    # e.g. DIGIT FIVE
                      .comb(.uc)    # Contains the uppercase of the word
{             }o  # Pass this list to another function
                  # That converts the list to a string
 TR"⁢ʼn؊⟠"*/൰ "    #"# And parse out the garbage characters that were wrong
                  # INVISIBLE TIMES => "*"
                  # LOZENGE DIVIDED BY HORIZONTAL RULE => "/"
                  # ARABIC-INDIC PER TEN THOUSAND SIGN => "൰" (value ten)
                  # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE => " "
{S:g/" ҈"/00/}o   # Replace the character for "hundred" with 00

{                                }o   # And finally combine with
 S:g/(<:N>+)+%\s/   # Substitute each number-like character separated by spaces
                /({'+'X$0})/   # With the numbers prefixed by '+'s, in brackets
               # This works because Perl 6 supports numeric unicode literals, like
               # ፳ => 20, ፴ => 30, ፺ => 90, etc.
                            .EVAL   # And finally evaluate the whole expression

7

Pythonの2333 ... 284 277 275バイト

lambda s:eval(''.join((list('+-/*')+[`N(w,0)*100+N(w,2)`])['pmdt'.find(w)]for w in re.split(' *(?:(p|m)|(t|d)i|by).*? ',s)if w))
N=lambda x,y:sum(10*(w[-3:]in'lveen')+'zeontwthfofisiseeiniteel'.find(w[:2])/2*10**('y'in w)for w in x.rpartition('hundred')[y].split())
import re

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


5

Wolfram言語95 94 82バイト

Interpreter["SemanticExpression"][#~StringReplace~{"me "->"mes ","plus m"->"m"}]&

# 純関数の入力を表します。

必要に応じて、StringReplace「time」を「time」に、「plus minus」を「minus」に(それぞれ"me "->"mes ""plus m"->"m「」を介して)置き換えます。で推奨される短縮された置換フォームは、lirtosiast12バイトを節約しました。

Interpreter["SemanticExpression"] 残りすべてを行います。


あなたは変更することができます"time "->"times ""me"->"mes"して"plus minus"->"minus""plus m"->"m"
リトシアスト

はい。素晴らしい提案。
DavidC

3

05AB1E166の 147 141 139 135 バイト

„byK“¡×€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š—¿áÓÁÏ“#vyN:}'tK'…§¦'+T«:'°¡„ *т«©:.•1×j›o!ĆÖ•3ôŽ9oS:'y®¨:©“‰´Øè„Æ€ººß“'tK#UX¡εð¡õK2ôJ.EO}®áX"+-**/"S:Sðì.ιJ.E

あまりにも長い..ここから下にゴルフしようとします。

@Emignaのおかげで-4バイト。@JoKingの
おかげで-2バイト。

オンラインそれを試してみたり、すべてのテストケースを確認してください

説明:

byK                 # Remove "by" from the (implicit) input-string
“¡×€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š—¿áÓÁÏ“
                     # Push string "zero one two three four five six seven eight nine ten eleven twelve"
 #                   # Split by spaces
  v   }              # Loop over each of these items:
   yN:               #  Replace the item with its 0-indexed index
'tK                 '# Remove all "t"
'…§¦                '# Push string "teen", and remove the first character: "een"
    '+              '# Push string "+"
      T«             # Append 10: "+10"
        :            # Replace all "een" with "+10"
'°¡                 '# Push string "hundred"
    *               # Push string " *"
      т«             # Append 100: " *100"
        ©            # Store it in the register (without popping)
         :           # Replace all "hundred" with " *100"
.•4º»Ÿć'Rþн•        '# Push string "wenhirforfif"
            3ô       # Split the string into parts of size 3: ["wen","hir","for","fif"]
              Ž9o    # Push integer 2345
                 S   # Split to digits: [2,3,4,5]
                  :  # Replace each
'y                  '# Push string "y"
  ®                  # Push the " *100" from the register
   ¨                 # Remove the last character: " *10"
    :                # Replace all "y" with " *10"
©                    # Save the current string in the register (without popping)
 “‰´Øè„Æ€ººß“        # Push string "plus minus times time divided"
             'tK    '# Remove all "t": "plus minus imes ime divided"
                #    # Split by spaces: ["plus","minus","imes","ime","divided"]
                 U   # Pop and save it in variable `X`
                  X  # And push variable `X` back again
                   ¡ # Split the string by those operator-strings
ε          }         # Map each substring to:
 ð¡                  #  Split by spaces (NOTE: cannot be `#`; if the string contains no
                     #   spaces, `#` remains string, whereas `ð¡` wraps it in a list)
   õK                #  Remove empty strings from the list
     2ô              #  Split the list into parts of two
       J             #  Join each pair together
        .E           #  Evaluate each as a Python `eval` expression
          O          #  Sum them
®                    # Put the string from the register to the stack again
 á                   # Remove everything except for letters
  X                  # Push variable `X`: ["plus","minus","imes","ime","divided"]
   "+-**/"           # Push string "+-**/"
          S          # Split to characters: ["+","-","*","*","/"]
           :         # Replace each
S                    # Split the string of operators to loose characters
 ðì                  # Prepend a space before each
                   # Interweave all sums with these operator-characters
     J               # Join everything together to a single string
.E                   # Evaluate each as a Python `eval` expression (and output implicitly)

私のこの05AB1Eヒントを参照してください(セクションがどのように辞書を使用するには?どのように辞書の圧縮文字列への一部ではありません?、そしてどのように大きな整数を圧縮する?どのように理解するために“¡×€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š—¿áÓÁÏ“'…§'°¡.•4º»Ÿć'Rþн•Ž9o、と“‰´Øè„Æ€ººß“仕事を。

ステップバイステップの例:

  • 入力: two hundred twenty two divided by two times minus fifty seven plus three hundred eighteen minus minus ten
  • ステップ1:「by」を削除します。 two hundred twenty two divided two times minus fifty seven plus three hundred eighteen minus minus ten
  • ステップ2:正しい数値で「ゼロ」から「12」に変換します。 2 hundred twenty 2 divided 2 times minus fifty 7 plus 3 hundred 8een minus minus 10
  • ステップ3:すべての「t」を削除します。 2 hundred weny 2 divided 2 imes minus fify 7 plus 3 hundred 8een minus minus 10
  • ステップ4:すべての「een」を「+10」に置き換えます。 2 hundred weny 2 divided 2 imes minus fify 7 plus 3 hundred 8+10 minus minus 10
  • ステップ5:すべての「百」を「* 100」に置き換えます。 2 *100 weny 2 divided 2 imes minus fify 7 plus 3 *100 8+10 minus minus 10
  • ステップ6:すべての["wen"、 "hir"、 "for"、 "fif"]を正しい数字に置き換えます。 2 *100 2y 2 divided 2 imes minus 5y 7 plus 3 *100 8+10 minus minus 10
  • ステップ7:すべての「y」を「* 10」に置き換えます。 2 *100 2 *10 2 divided 2 imes minus 5 *10 7 plus 3 *100 8+10 minus minus 10
  • ステップ8:["plus"、 "minus"、 "ime"、 "imes"、 "divided"]で分割: ["2 *100 2 *10 2 "," 2 "," "," 5 *10 7 "," 3 *100 8+10 "," "," 10"]
  • ステップ9:スペースでそれぞれを分割します。 [["2","","*100","2","*10","2",""],["","","2",""],["",""],["","5","*10","7",""],["","3","","*100","8+10",""],["",""],["","10"]]
  • ステップ10:空のアイテムを削除します。 [["2","*100","2","*10","2"],["2"],[],["5","*10","7"],["3","*100","8+10"],[],["10"]]
  • ステップ11:サイズ2の部分に分割して結合します。 [["2*100","2*10","2"],["2"],"",["5*10","7"],["3*100","8+10"],"",["10"]]
  • ステップ12:eval各Python :[[200,20,2],[2],"",[50,7],[300,18],"",[10]]
  • ステップ13:それぞれを合計します。 [222,2,"",57,318,"",10]
  • ステップ14:レジスタから文字列を再プッシュし、文字を除くすべてを削除します。 dividedimesminusplusminusminus
  • ステップ15:「プラス」、「マイナス」、「imes」、「ime」、「分割」を演算子文字に置き換え、スペースを先頭に追加します。 [" /"," *"," -"," +"," -"," -"]
  • ステップ16:両方を織り交ぜて結合します。 222 /2 * -57 +318 - -10
  • 出力: Python eval文字列、および暗黙的に出力:-5999.0

ゼロから解決策を作ろうとしたり、詳細に検討したことはありませんでしたが、私はゴルフに気づきました。
エミグナ

@Emignaありがとう!
ケビンクルーッセン

2

SFK572の 449 423バイト

これはすべて1行にすることもできますが、それを読むためにスペースではなく改行を使用しました。

xed -i
_plus_+_
_minus_-_
_times[ortext]time_*_
_divided?by_/_
+xed
"_[white][2 chars of a-z][chars of a-z]ty_[parts 1,2]0_"
"_[white][2 chars of a-z][chars of a-z]een_[part1]1[part2]_"
_ten_10_
_lev_11_
_twe_12_
+xed
_ze_0_
_on_1_
_tw_2_
_th_3_
_fo_4_
_fi_5_
_si_6_
_se_7_
_ei_8_
_ni_9_
+xed
_0[white][keep][digit]__
"_[chars of e-z ]__"
+xed
"_?dd[keep][2 digits]_[part1]_"
_?dd[keep][digit]_[part1]0_
_dd_00_
+calc #text

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

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