Máy tính có chữ


14

Một phiên bản đơn giản của máy tính số tiếng Anh

Bài tập

Viết chương trình lấy một chuỗi làm đầu vào và xuất kết quả của biểu thức.

Quy tắc

Chuỗi đầu vào sẽ được diễn đạt và không phải là số.

Sẽ không có dấu ngoặc đơn.

Thứ tự tính toán sẽ được chia, nhân, trừ rồi cộng.

Đối với các hoạt động tương tự, các tính toán phải được thực hiện từ trái sang phải.

Tất cả các số đầu vào sẽ là số nguyên từ -999 đến 999 (bao gồm cả hai)

Đầu ra sẽ là một số nguyên của bất kỳ phạm vi.

Bộ phận sẽ luôn luôn chia hết và số 0 sẽ không bao giờ là mẫu số.

Hạn chế của trường hợp cho đầu vào là tùy chọn. Bạn không phải kiểm tra tính hợp lệ của đầu vào.

Định dạng số

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

Đối với số âm: Thêm vào minustương đương dương của nó

Định dạng hoạt động

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

Ví dụ:

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

Đây là môn đánh gôn nên mã ngắn nhất sẽ thắng


1
Bản sao? - Tôi nghĩ rằng đủ gần để được coi là như vậy.
Kirill L.

2
Nó thực sự rất gần. Nhưng tôi nghĩ rằng cái này được chỉ định tốt hơn và có những hạn chế hợp lý hơn.
Arnauld

1
@Arnauld Tôi sẽ giữ điều này sau đó nhưng nếu người khác nghĩ khác, chỉ cần đánh dấu nó là trùng lặp.
Vedant Kandoi

15
Tôi nói one times two. Là sử dụng timebình thường?
Jo King

2
Tôi nghĩ rằng bạn có nghĩa là 'một lần s bảy trăm'?
ngerak

Câu trả lời:


18

JavaScript (ES6), 256 252 249 235 byte

Đã lưu 3 byte nhờ @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)

Hãy thử trực tuyến!

Làm sao?

WLTôiW+L+W

Số

 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"

Người vận hành

 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"

Diễn dịch

nTôi

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 byte

-13 byte nhờ nwellnhof!

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

Hãy thử trực tuyến!

univalđể giải cứu một lần nữa! Đây là (hiện tại) thậm chí đánh bại các ngôn ngữ golf như 05AB1E!

Giải trình:

*.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 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

Hãy thử trực tuyến!


5

Ngôn ngữ Wolfram 95 94 82 byte

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

# đại diện cho đầu vào cho hàm thuần túy.

Nếu cần, StringReplacethay thế "thời gian" bằng thời gian "," cộng trừ "bằng" trừ "(thông qua "me "->"mes ", "plus m"->"m", tương ứng). Các hình thức thay thế rút ngắn, được đề xuất bởilirtosiast , đã lưu 12 byte.

Interpreter["SemanticExpression"] làm tất cả phần còn lại


Bạn có thể thay đổi "time "->"times "thành "me"->"mes""plus minus"->"minus"để "plus m"->"m"?
lirtosiast

Đúng. Gợi ý tuyệt vời.
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

Cách quá lâu .. Sẽ cố gắng đánh gôn từ đây.

-4 byte nhờ @Emigna .
-2 byte nhờ @JoKing .

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

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)

Xem 05AB1E mẹo này của tôi (phần Làm thế nào để sử dụng từ điển? , Làm thế nào để chuỗi nén không nằm trong từ điển?Làm thế nào để nén các số nguyên lớn? ) Để hiểu làm thế nào “¡×€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š—¿áÓÁÏ“, '…§, '°¡, .•4º»Ÿć'Rþн•, Ž9o, và “‰´Øè„Æ€ººß“làm việc.

Từng bước ví dụ:

  • Đầu vào: two hundred twenty two divided by two times minus fifty seven plus three hundred eighteen minus minus ten
  • Bước 1: Xóa "bằng": two hundred twenty two divided two times minus fifty seven plus three hundred eighteen minus minus ten
  • Bước 2: Chuyển đổi "không" sang "mười hai" với số chính xác: 2 hundred twenty 2 divided 2 times minus fifty 7 plus 3 hundred 8een minus minus 10
  • Bước 3: Xóa tất cả "t": 2 hundred weny 2 divided 2 imes minus fify 7 plus 3 hundred 8een minus minus 10
  • Bước 4: Thay thế tất cả "een" bằng "+10": 2 hundred weny 2 divided 2 imes minus fify 7 plus 3 hundred 8+10 minus minus 10
  • Bước 5: Thay thế tất cả "trăm" bằng "* 100": 2 *100 weny 2 divided 2 imes minus fify 7 plus 3 *100 8+10 minus minus 10
  • Bước 6: Thay thế tất cả ["wen", "hir", "cho", "fif"] bằng chữ số chính xác: 2 *100 2y 2 divided 2 imes minus 5y 7 plus 3 *100 8+10 minus minus 10
  • Bước 7: Thay thế tất cả "y" bằng "* 10": 2 *100 2 *10 2 divided 2 imes minus 5 *10 7 plus 3 *100 8+10 minus minus 10
  • Bước 8: Chia theo ["cộng", "trừ", "ime", "imes", "chia"]: ["2 *100 2 *10 2 "," 2 "," "," 5 *10 7 "," 3 *100 8+10 "," "," 10"]
  • Bước 9: Tách từng khoảng trắng: [["2","","*100","2","*10","2",""],["","","2",""],["",""],["","5","*10","7",""],["","3","","*100","8+10",""],["",""],["","10"]]
  • Bước 10: Xóa các mục trống: [["2","*100","2","*10","2"],["2"],[],["5","*10","7"],["3","*100","8+10"],[],["10"]]
  • Bước 11: Chia thành các phần của kích thước 2 và tham gia: [["2*100","2*10","2"],["2"],"",["5*10","7"],["3*100","8+10"],"",["10"]]
  • Bước 12: Python evalmỗi cái:[[200,20,2],[2],"",[50,7],[300,18],"",[10]]
  • Bước 13: Tổng hợp mỗi: [222,2,"",57,318,"",10]
  • Bước 14: Đẩy lại chuỗi từ thanh ghi và xóa mọi thứ trừ các chữ cái: dividedimesminusplusminusminus
  • Bước 15: Thay thế "cộng", "trừ", "imes", "ime", "chia" bằng các ký tự toán tử và thêm chúng vào khoảng trắng: [" /"," *"," -"," +"," -"," -"]
  • Bước 16: Đan xen và kết hợp cả hai cùng nhau: 222 /2 * -57 +318 - -10
  • Đầu ra: Python evalchuỗi và đầu ra ngầm:-5999.0

Haven đã không cố gắng thực hiện một giải pháp từ đầu hoặc nghiên cứu chi tiết của bạn, nhưng tôi nhận thấy một golf .
Emigna

@Emigna Cảm ơn!
Kevin Cruijssen

2

sfk , 572 449 423 byte

Tất cả điều này có thể là một dòng, nhưng với mục đích đọc nó, tôi đã sử dụng các dòng mới thay vì khoảng trắng.

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

Hãy thử trực tuyến!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.