Kalkulator Worded

14

Versi sederhana dari kalkulator angka bahasa Inggris

Tugas

Tulis program yang menggunakan string sebagai input dan output hasil dari ekspresi.

Aturan

String input akan dikata dan bukan bilangan.

Tidak akan ada tanda kurung.

Urutan perhitungan akan dibagi, dikalikan, kurangi kemudian tambahkan.

Untuk operasi yang sama, perhitungan harus dilakukan dari kiri ke kanan.

Semua angka input akan berupa bilangan bulat dari -999 hingga 999 (keduanya termasuk)

Output akan menjadi bilangan bulat dari rentang apa pun.

Pembagian akan selalu dapat dibagi dengan sempurna dan nol tidak akan pernah menjadi penyebut.

Pembatasan case untuk input adalah opsional. Anda tidak perlu memeriksa validitas input.

Format Angka

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

Untuk angka negatif: Tambahkan minuske ekivalen positifnya

Format Operasi

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

Contoh:

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

Ini adalah kode-golf sehingga kode terpendek menang

Vedant Kandoi
sumber
1
Duplikat? - Saya pikir itu cukup dekat untuk dipertimbangkan.
Kirill L.
2
Sangat dekat sekali. Tapi saya pikir ini lebih baik dan memiliki batasan yang lebih masuk akal.
Arnauld
1
@Arnauld saya akan membiarkan ini tetap terbuka tetapi jika orang lain berpikir berbeda, cukup tandai sebagai duplikat.
Vedant Kandoi
15
Saya katakan one times two. Apakah menggunakan timenormal?
Jo King
2
Saya pikir Anda berarti 'satu waktu s tujuh ratus'?
ouflak

Jawaban:

18

JavaScript (ES6), 257 252 249 235 byte

Disimpan 3 byte berkat @Shaggy

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)

Cobalah online!

Bagaimana?

WL.sayaW+L.+W

Angka

 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"

Operator

 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"

Penafsiran

nsaya

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
  )                       //
Arnauld
sumber
11

Perl 6 , 170 139 129 128 124 122 byte

-13 byte terima kasih kepada nwellnhof!

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

Cobalah online!

univaluntuk menyelamatkan lagi! Ini (saat ini) bahkan mengalahkan bahasa golf seperti 05AB1E!

Penjelasan:

*.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
Jo King
sumber
7

Python 2 , 333 ... 284 277 275 byte

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

Cobalah online!

TFeld
sumber
5

Bahasa Wolfram 95 94 82 byte

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

# mewakili input untuk fungsi murni.

Jika perlu, StringReplacemenggantikan "waktu" dengan waktu " "plus minus" dengan "minus"(melalui "me "->"mes ", "plus m"->"m", masing-masing). Formulir penggantian yang dipersingkat, disarankan oleh lirtosiast, disimpan 12 byte.

Interpreter["SemanticExpression"] melakukan sisanya.

DavidC
sumber
Bisakah Anda mengubah "time "->"times "ke "me"->"mes"dan "plus minus"->"minus"ke "plus m"->"m"?
lirtosiast
Iya. Saran yang bagus.
DavidC
3

05AB1E , 166 147 141 139 135 byte

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

Terlalu lama .. Akan mencoba golf turun dari sini.

-4 byte terima kasih kepada @Emigna .
-2 byte terima kasih kepada @ JoKing .

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

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)

Lihat ini 05AB1E ujung tambang (bagian Cara menggunakan kamus? , Cara string kompres bukan bagian dari kamus? , Dan Cara kompres bilangan bulat besar? ) Untuk memahami bagaimana “¡×€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š—¿áÓÁÏ“, '…§, '°¡, .•4º»Ÿć'Rþн•, Ž9o, dan “‰´Øè„Æ€ººß“pekerjaan.

Contoh langkah demi langkah:

  • Memasukkan: two hundred twenty two divided by two times minus fifty seven plus three hundred eighteen minus minus ten
  • Langkah 1: Hapus "oleh": two hundred twenty two divided two times minus fifty seven plus three hundred eighteen minus minus ten
  • Langkah 2: Ubah "nol" menjadi "dua belas" dengan angka yang benar: 2 hundred twenty 2 divided 2 times minus fifty 7 plus 3 hundred 8een minus minus 10
  • Langkah 3: Hapus semua "t": 2 hundred weny 2 divided 2 imes minus fify 7 plus 3 hundred 8een minus minus 10
  • Langkah 4: Ganti semua "een" dengan "+10": 2 hundred weny 2 divided 2 imes minus fify 7 plus 3 hundred 8+10 minus minus 10
  • Langkah 5: Ganti semua "seratus" dengan "* 100": 2 *100 weny 2 divided 2 imes minus fify 7 plus 3 *100 8+10 minus minus 10
  • Langkah 6: Ganti semua ["wen", "hir", "untuk", "fif"] dengan digit yang benar: 2 *100 2y 2 divided 2 imes minus 5y 7 plus 3 *100 8+10 minus minus 10
  • Langkah 7: Ganti semua "y" dengan "* 10": 2 *100 2 *10 2 divided 2 imes minus 5 *10 7 plus 3 *100 8+10 minus minus 10
  • Langkah 8: Dibagi dengan ["plus", "minus", "ime", "imes", "dibagi"]: ["2 *100 2 *10 2 "," 2 "," "," 5 *10 7 "," 3 *100 8+10 "," "," 10"]
  • Langkah 9: Bagi masing-masing pada spasi: [["2","","*100","2","*10","2",""],["","","2",""],["",""],["","5","*10","7",""],["","3","","*100","8+10",""],["",""],["","10"]]
  • Langkah 10: Hapus item kosong: [["2","*100","2","*10","2"],["2"],[],["5","*10","7"],["3","*100","8+10"],[],["10"]]
  • Langkah 11: Bagi menjadi beberapa ukuran 2 dan bergabung: [["2*100","2*10","2"],["2"],"",["5*10","7"],["3*100","8+10"],"",["10"]]
  • Langkah 12: evalSetiap Python :[[200,20,2],[2],"",[50,7],[300,18],"",[10]]
  • Langkah 13: Jumlahkan masing-masing: [222,2,"",57,318,"",10]
  • Langkah 14: Dorong kembali string dari register, dan hapus semuanya kecuali huruf: dividedimesminusplusminusminus
  • Langkah 15: Ganti "plus", "minus", "imes", "ime", "dibagi" dengan karakter operator, dan tambahkan mereka dengan spasi: [" /"," *"," -"," +"," -"," -"]
  • Langkah 16: Jalin dan gabungkan keduanya: 222 /2 * -57 +318 - -10
  • Output: Python evalstring, dan output secara implisit:-5999.0
Kevin Cruijssen
sumber
Belum mencoba membuat solusi dari awal atau mempelajari Anda secara detail, tetapi saya perhatikan satu golf .
Emigna
@Emigna Terima kasih!
Kevin Cruijssen 6-18
2

sfk , 572 449 423 byte

Ini semua bisa menjadi satu baris, tetapi untuk tujuan membacanya saya menggunakan baris baru, bukan spasi.

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

Cobalah online!

Suram
sumber