Chuyển đổi số nguyên sang từ tiếng Anh


21

Mục tiêu của mã golf này là chuyển đổi số nguyên sang các từ tiếng Anh.

Chương trình nhắc nhở đầu vào. Nếu đầu vào này không phải là số nguyên, hãy in NaN. Nếu nó là một số nguyên, chuyển đổi nó thành các từ tiếng Anh và in những từ này. Đầu vào tối thiểu: 0 (không). Đầu vào tối đa: 9000 (chín nghìn).
Vì vậy, 5trả về five(trường hợp không quan trọng) và 500trả về five hundredhoặc five-hundred(dấu gạch ngang không quan trọng).

Một số quy tắc khác:

A onetrước hundredhoặc thousandlà tùy chọn: one hundredlà chính xác, nhưng hundredcũng vậy (nếu đầu vào là 100tất nhiên).

Từ andtrong ví dụ one hundred and forty fivelà tùy chọn quá.

Vấn đề khoảng trắng. Vì vậy, cho 500, five-hundredhoặc five hundredlà chính xác, nhưng fivehundredkhông phải.

Chúc may mắn!


Có một câu trả lời vô căn cứ ở đây rgagnon.com/javadetails/java-0426.html .

Câu trả lời này trong SO thực hiện công cụ tương tự nhưng không phải là môn đánh gôn.
ST3

Câu trả lời:


7

Perl 281 byte

print+0eq($_=<>)?Zero:"@{[((@0=($z,One,Two,Three,Four,Five,@2=(Six,Seven),
Eight,Nine,Ten,Eleven,Twelve,map$_.teen,Thir,Four,@1=(Fif,@2,Eigh,Nine)))
[$_/1e3],Thousand)x($_>999),($0[($_%=1e3)/100],Hundred)x($_>99),
($_%=100)>19?((Twen,Thir,For,@1)[$_/10-2].ty,$0[$_%10]):$0[$_]]}"||NaN

Dòng mới được thêm cho sự tỉnh táo ngang. Ở trên có thể được sử dụng tương tác, hoặc bằng cách đặt nó một giá trị thông qua stdin.

Hoạt động chính xác cho tất cả các giá trị số nguyên trong phạm vi [0, 19999] , các giá trị ngoài phạm vi này thể hiện hành vi không xác định. Các giá trị không nguyên sẽ bị cắt cụt về 0 và do đó, chỉ các giá trị thực sự không phải là số sẽ báo cáo NaN.

Sử dụng mẫu:

for $n (14, 42, 762, 2000, 6012, 19791, 1e9, foobar, 17.2, -3) {
  print "$n: ", `echo $n | perl spoken-numbers.pl`, $/;
}

Đầu ra mẫu:

14: Fourteen
42: Forty Two
762: Seven Hundred Sixty Two
2000: Two Thousand 
6012: Six Thousand Twelve
19791: Nineteen Thousand Seven Hundred Ninety One
1000000000: Thousand 
foobar: NaN
17.2: Seventeen
-3: Nine Hundred Ninety Seven

"1000000000: Ngàn"? Và không nên in 17.2 "NaN"?
DavidC

5
@DavidCarraher "... các giá trị nằm ngoài phạm vi này thể hiện hành vi không xác định . Các giá trị không nguyên sẽ bị cắt về 0 và do đó, chỉ các giá trị thực sự không phải là số sẽ báo cáo NaN."
primo

Tôi không phải là chuyên gia về Perl, vì vậy tôi hỏi câu hỏi này: chương trình này có nhắc nhở về đầu vào không?
Chương trìnhFOX

@ProgramFOX Tôi đã cập nhật nó để đọc một giá trị từ stdin (nếu chạy tương tác, nó sẽ nhắc người dùng về một giá trị), thay vì dưới dạng hàm.
primo

13

JavaScript (375)

Có lẽ là một nỗ lực khủng khiếp, nhưng dù sao, ở đây đi ...

alert(function N(s,z){return O="zero,one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir,,fif,,,eigh,,,,twen,,for".split(","),(z?O[s]||O[s-10]||O[s-20]:s<13?N(s,1):s<20?N(s,1)+"teen":s<100?N(a=20+(s/10|0),1)+"ty"+(s%10?" "+N(s%10):""):s<1e3?N(s/100|0)+" hundred"+(s%100?" "+N(s%100):""):s<1e5?N(s/1e3|0)+" thousand"+(s%1e3?" "+N(s%1e3):""):0)||NaN}(prompt()))

Khá in (như một chức năng):

function N(s,z) {
  return O = "zero,one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir,,fif,,,eigh,,,,twen,,for".split(","),
      (z? O[s] || O[s-10] || O[s-20]
       : s < 13?  N(s,1)
       : s < 20?  N(s,1) + "teen"
       : s < 100? N(a=20+(s/10|0),1) + "ty" + (s%10?" "+N(s%10):"")
       : s < 1e3?  N(s/100|0) +  " hundred" + (s%100?" "+N(s%100):"")
       : s < 1e5?  N(s/1e3|0) + " thousand" + (s%1e3?" "+N(s%1e3):"") : 0) || NaN
}

Chuyển đổi mẫu (lưu ý rằng nó thậm chí xuất ra NaNkhi vượt quá giới hạn, tức là đầu vào không hợp lệ):

540: five hundred forty
4711: four thousand seven hundred eleven
7382: seven thousand three hundred eighty two
1992: one thousand nine hundred ninety two
hutenosa: NaN
1000000000: NaN
-3: NaN

+1khá khó để làm tốt hơn trong một ngôn ngữ như javascript. (bạn có thể xóa khoảng trống trong N(s,z) {returnđể lưu 1 char)
làm lạnh toán học

Oh, haha, phải bỏ lỡ cái đó. Tôi dường như cũng đã bỏ lỡ một loạt các ký tự trong Ochuỗi. Tôi sẽ sửa nó ..
FireFly

11

Toán học 60 57

f = ToString@#~WolframAlpha~{{"NumberName", 1}, "Plaintext"} &

Sử dụng:

f[500]

năm trăm

Chỉnh sửa:

InputString[]~WolframAlpha~{{"NumberName", 1}, "Plaintext"}

3
Điều này không thực sự trả lời câu hỏi. Tôi đã nói rằng người dùng phải nhập một số (ví dụ sử dụng dòng lệnh hoặc hộp nhắc nhở), và sau đó chương trình của bạn sẽ xuất các từ (ví dụ trên dòng lệnh hoặc trong hộp thông báo). Mã của bạn chỉ là một chức năng để chuyển đổi nó và chương trình của bạn không yêu cầu nhập liệu.
Chương trìnhFOX

@ProgramFOX có ghi 'Người dùng nhập nội dung nào đó'. Điều đó không có nghĩa là 'Chương trình nhắc nhở đầu vào'.
MrZander

@MrZander: Chà, 'Chương trình nhắc nhập liệu' thực ra là điều tôi muốn nói. Tôi cập nhật câu hỏi của mình, nhưng tất nhiên, sẽ không công bằng nếu tôi không nêu lên câu trả lời của alephalpha, vì vậy anh ấy đã nhận được +1
ProgramFOX

8

Lisp, 72 56 ký tự

Tôi nhận ra 1) rằng cái này đã cũ và 2) nó hoàn toàn dựa vào thư viện chuẩn để hoạt động, nhưng thực tế là bạn có thể có được hệ thống in c-lisp để làm điều này luôn gây ấn tượng với tôi. Ngoài ra, trên thực tế, việc này lấy đầu vào từ người dùng, chuyển đổi và in nó.

(format t "~:[NaN~;~:*~r~]" (parse-integer (read-line) :junk-allowed t))

Nó có tổng cộng 72 ký tự.

  • :junk-allowed làm cho số nguyên parse trả về nil khi thất bại thay vì tăng lỗi.
  • ~:[if-nil~;if-non-nill] có điều kiện dựa trên nil, xử lý NaN khi cần thiết
  • ~:* sao lưu giải thích đối số để sử dụng lại đầu vào
  • ~r in số dưới dạng một chuỗi từ tiếng Anh, theo yêu cầu, ngoại trừ với dấu câu được sửa hoàn toàn

Mẫu vật:

17823658
seventeen million, eight hundred and twenty-three thousand, six hundred and fifty-eight

192hqfwoelkqhwef9812ho1289hg18hoif3h1o98g3hgq
NaN

Thông tin Lisp chủ yếu từ Lisp thực tế chung .

Chỉnh sửa, đánh golf đúng xuống còn 56 ký tự

(format t "~:[NaN~;~:*~r~]"(ignore-errors(floor(read))))

Phiên bản này hoạt động khá khác nhau. Thay vì đọc một dòng và chuyển đổi nó, nó gọi trình đọc lisp để diễn giải đầu vào là một biểu thức s lisp, cố gắng sử dụng nó như một số và nếu có bất kỳ lỗi nào được tạo ra sẽ bỏ qua chúng tạo ra nil để cung cấp chuỗi định dạng có điều kiện. Đây có thể là ví dụ đầu tiên tôi thấy về việc sản xuất một chương trình thực sự ngắn gọn ... Vui!

  • (read) Gọi trình đọc / trình phân tích cú pháp để đọc một biểu thức từ đầu vào tiêu chuẩn và chuyển đổi nó thành một đối tượng thích hợp
  • (floor) cố gắng chuyển đổi bất kỳ loại số nào thành số nguyên thấp hơn gần nhất, các loại không số làm cho nó phát sinh lỗi
  • (ignore-errors ...) thực hiện những gì nó nói trên hộp thiếc, nó nắm bắt và bỏ qua bất kỳ lỗi nào trong biểu thức kèm theo, trả về nil để cung cấp nhánh NaN của chuỗi định dạng

Chắc chắn không có vấn đề gì khi câu hỏi cũ :) Tôi đã chỉnh sửa câu trả lời của bạn để bao gồm tên ngôn ngữ và số ký tự trong một tiêu đề.
Chương trìnhFOX

Cảm ơn bạn đã chỉnh sửa, tôi chưa nhận được cú pháp Stack * cho những điều này. Đã quay lại và sửa một lỗi tôi đã làm trong phần mô tả điều kiện trong chuỗi định dạng là tốt.
Tom Scogland

3

PHP, 327 310 308 byte

<?$a=['',one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir,0,fif,0,0,eigh];echo($n=$argv[1])>999?$a[$n/1000].' thousand ':'',$n%1000>99?$a[$n/100%10].' hundred ':'',$n?($k=$n%100)<20?($a[$k]?:$a[$k%10]).[teen][$k<13]:[2=>twen,thir,'for',fif,six,seven,eigh,nine][$k/10].'ty '.$a[$k%10]:zero;

lấy số làm tham số, hoạt động cho 0 <= n <= 12999

phá vỡ

// define names
$a=['',one,two,three,four,five,six,seven,eight,nine,
    ten,eleven,twelve,thir,0,fif,0,0,eigh];
// print ...
echo
    ($n=$argv[1])>999?$a[$n/1000].' thousand ':'',                  // thousands
    $n%1000>99?$a[$n/100%10].' hundred ':'',                        // hundreds
    $n?
        // if remains <20:
        ($k=$n%100)<20?
            ($a[$k]?:$a[$k%10]) // no value at index (0,14,16,17,19)? value from index%10
            .[teen][$k<13]      // append "teen" for $k>12
        // else:
        :[2=>twen,thir,'for',fif,six,seven,eigh,nine][$k/10].'ty '  // tens
        .$a[$k%10]                                                  // ones
    // "zero" for $n==0
    :zero
;

2

SAS, 70 ký tự

data;window w n;display w;if n=. then put 'NaN';else put n words.;run;

Các câu lệnh windowdisplaymở ra dấu nhắc lệnh SAS. Đầu vào cho nđi trên dòng 1. Điều này tận dụng định dạng SAS words.sẽ in số dưới dạng một từ hoặc chuỗi từ với "và", "" và "-" khi thích hợp.


2

PHP

777 ký tự

Đây chắc chắn là một nỗ lực khủng khiếp, nhưng bạn không thể buộc tội tôi lợi dụng bất kỳ sơ hở nào, cộng với đó là một con số rất may mắn. Cảm ơn Chương trìnhFOX cho tiền boa.

<?php $i=9212;$b = array('zero','one','two','three','four','five','six','seven','eight','nine');$t='teen';$c = array('ten','eleven','tweleve','thir'.$t,$b[4].$t,'fif'.$t,$b[6].$t,$b[7].$t,$b[8].$t,$b[9].$t);$d = array('','','twenty','thirty','fourty','fifty','sixty','seventy','eighty','ninety');$e='hundred';$f='thousand';$j=str_split($i);if (strlen($i)===1){$a=$b[$i];}elseif (strlen($i)===3){$k=1;$a=$b[$j[0]].' '.$e.' '.x($j,$k);}elseif (strlen($i)===4){$k=2;$a=$b[$j[0]].' '.$f.' '.$b[$j[1]].' '.$e.' '.x($j,$k);}elseif (substr($i, -2, 1)==='1'){$a=$c[$j[1]];}else{$a=$d[$j[0]].' '.$b[$j[1]];}$a = str_replace('zero hundred','',$a);echo $a;function x($j,$k){global $i, $b, $c, $d;if (substr($i, -2, 1)==='1'){return $c[$j[$k+1]];}else{return $d[$j[$k]].' '.$b[$j[$k+1]];}}

Tay dài

<?php
// Input
$i=9212;
// 0-9
$b = array('zero','one','two','three','four','five','six','seven','eight','nine');
// 10-19 (Very tricky)
$t='teen';
$c = array('ten','eleven','tweleve','thir'.$t,$b[4].$t,'fif'.$t,$b[6].$t,$b[7].$t,$b[8].$t,$b[9].$t); 
// Left digit of 20-99
$d = array('','','twenty','thirty','fourty','fifty','sixty','seventy','eighty','ninety');
// Hundreds
$e='hundred';
// Thousands
$f='thousand';
// Split input
$j=str_split($i);
// 1 digit inputs
if (strlen($i)===1){$a=$b[$i];}
// 3 digit input
elseif (strlen($i)===3){$k=1;$a=$b[$j[0]].' '.$e.' '.x($j,$k);}
// 4 digit input
elseif (strlen($i)===4){$k=2;$a=$b[$j[0]].' '.$f.' '.$b[$j[1]].' '.$e.' '.x($j,$k);}
// 10-19
elseif (substr($i, -2, 1)==='1'){$a=$c[$j[1]];}
// 20-99
else{$a=$d[$j[0]].' '.$b[$j[1]];}
// Fix for thousand numbers
$a = str_replace('zero hundred','',$a);
// Result
echo $a;
// Abstracted function last 2 digits for 3 and 4 digit numbers
function x($j,$k){
    global $i, $b, $c, $d;
    // 10-19
    if (substr($i, -2, 1)==='1'){return $c[$j[$k+1]];}
    // 20-99
    else{return $d[$j[$k]].' '.$b[$j[$k+1]];}
}

1
Tôi nghĩ bạn có thể rút ngắn mã của mình bằng cách tạo các mảng như thế này : array('zero','one','two').
Chương trìnhFOX

@ProgramFOX hoặc thậm chí ['zero','one','two'](php 5.4+). Và nếu bạn không phiền E_NOTICE, [zero,one,two]cũng sẽ làm việc.
primo

Tôi nên cập nhật nó, nhưng 777 là một con số may mắn.
Ngỗng

+1 cho những nỗ lực của bạn. PHP là đại diện một cách bi thảm trong mã golf.
primo

1

Con trăn 2.x - 378

Đạo hàm của Fireflys trả lời, mặc dù bằng cách thay đổi Pđể bao gồm hàng triệu hoặc hàng nghìn tỷ, v.v .. nó có thể được sử dụng đệ quy cho bất kỳ phạm vi số dương nào. Điều này cũng hỗ trợ các giá trị lên tới 999.999

O=",one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir,,fif,,,eigh,,,,twen,thir,for,fif,,,eigh,".split(",")
P=",thousand".split(',')
def N(s,p=0):
 h,s=divmod(s,1000);x=N(h,p+1)if h>0 else" "
 if s<20:x+=O[s]or O[s-10]+["","teen"][s>12]
 elif s<100:x+=(O[s/10+20]or O[s/10])+"ty"+N(s%10)
 else:x+=N(s/100)+"hundred"+N(s%100)
 return x+" "+P[p]
print N(input())

Kiểm tra mẫu (đầu vào là <<<, đầu ra là >>>):

<<< 1234
>>> one thousand two hundred thirty four

<<< 999999
>>>  nine hundred ninety nine   thousand nine hundred ninety nine

Mặc dù, nếu ai đó có thể giải thích vấn đề "đệm tràn" kỳ lạ này mà tôi có, thì đó sẽ là ...

<<< -1
>>>  nine hundred ninety nine

<<< -2
>>>  nine hundred ninety eight

print divmod(-2,1000) #-> (-1, 998)
primo

Ồ dĩ nhiên rồi. Tôi đã nghĩ rằng nó có thể có một giá trị tuyệt đối hoặc một cái gì đó. Nhưng có -1*1000và "phần còn lại" của 998.

1

SmileBASIC, 365 Ba trăm Bốn mươi bảy byte

DIM N$[22]D$="OneTwoThreeFourFiveSixSevenEightNineTenElevenTwelveThirFourFifSixSevenEighNineTwenFor
WHILE LEN(D$)INC I,D$[0]<"_
INC N$[I],SHIFT(D$)WEND
INPUT N
W=N MOD 100C%=N/100MOD 10M%=N/1E3T=W<20X=W/10>>0?(N$[M%]+" Thousand ")*!!M%+(N$[C%]+" Hundred ")*!!C%+(N$[X+10+(X==2)*8+(X==4)*7]+"ty "+N$[N MOD 10])*!T+N$[W*T]+"teen"*(T&&W>12)+"Zero"*!N

Có một khoảng trắng ở cuối nếu một hoặc hai chữ số cuối cùng là 0.


0

MOO - 55 ký tự

player:tell($string_utils:english_number(read(player)))

Hoặc, nếu tôi không cần in ra "stdout" - 42 ký tự: $string_utils:english_number(read(player))

Lưu ý: mã này không in bất kỳ lời nhắc nào đến đầu ra tiêu chuẩn và in zerothay vì NaNkhi đầu vào không phải là số.

Là một phần thưởng, mã này có thể xử lý bất kỳ số nào trong giới hạn của ngôn ngữ moo ( 2147483647- -2147483648).


0

Ngôn ngữ Wolfram 27 40 byte

Sử dụng hàm riêng , IntegerName.

 Check[Input[]~IntegerName~"Words","NaN"]

Các lời nhắc trên cho đầu vào của người dùng. Việc triển khai hiện tại trả về "NaN" nếu người dùng nhập bất cứ thứ gì ngoài số nguyên.


Một số ví dụ (với đầu vào được đặt trước) :

 Check[243~IntegerName~"Words","NaN"]

hai trăm bốn mươi ba


 Check[1234567890~IntegerName~"Words","NaN"]   

một tỷ, hai trăm ba mươi tư triệu, năm trăm sáu mươi bảy nghìn, tám trăm chín mươi


 Check["abc"~IntegerName~"Words","NaN"]  

NaN


0

Python 2 , 333 byte

def f(n):S=str.split;D=S('z one two three four five six seven eight nine');K=' fif six seven eigh nine';k=n/1000;n,m=n/100%10,n%100;e,d=m/10,m%10;return' '.join([k and f(k),'thousand']*(k>0)+[D[n],'hundred']*(n>0)+([S('ten eleven twelve thir four'+K)[d]+'teen'*(d>2)]if 9<m<20else[S('twen thir for'+K)[e-2]+'ty']*(e>0)+[D[d]]*(d>0)))

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

Điều này tốt cho 1 đến 999.999, bao gồm.


0

Pyth, 239 242 byte

L:rjdb6"  +"dAm+cd;"nine"," one two three four five six seven eight""  twen thir for fif six seven eigh"|y_.ey+Wk.e?Y?thZjd,?hZ+@HhZ"ty"""@GeZ@+c"ten eleven twelve"d+R"teen"+c"thir four"d>H5eZ?hZ+@GhZ" hundred"""c.[03_b]1"thousand"c_jQT3"zero

Đầu vào là một số nguyên trong phạm vi [0-999.999]. Hãy thử trực tuyến tại đây . Giải thích đang chờ xử lý.

Phiên bản trước, hoạt động rất giống nhau, nhưng không hỗ trợ 0:

L:rjdb6"  +"dJc" one two three four five six seven eight nine"dKc"  twen thir for fif six seven eigh nine"dy_.ey+Wk.e?Y?thZjd,?hZ+@KhZ"ty"""@JeZ@+c"ten eleven twelve"d+R"teen"+c"thir four"d>K5eZ?hZ+@JhZ" hundred"""c.[03_b]1"thousand"c_jQT3

Giải thích về phiên bản trước:

Implicit: Q=eval(input()), d=" "

Step 1: output formatting helper function
L:rjdb6"  +"d   
L               Define a function, y(b):
   jdb          Join b on spaces
  r   6         Strip whitespace from beginning and end
 :              In the above, replace...
       "  +"    ... strings of more than one space...
            d   ... with a single space

Step 2: Define number lookup lists
Jc"..."dKc"..."d   
  "..."            Lookup string
 c     d           Split the above on spaces
J                  Store in J - this is list of unit names
        Kc"..."d   As above, but storing in K - this is list of tens names, without "ty"

Step 3: Bringing it all together
y_.ey+Wk.e?Y?thZjd,?hZ+@KhZ"ty"""@JeZ@+c"ten eleven twelve"d+R"teen"+c"thir four"d>K5eZ?hZ+@JhZ" hundred"""c.[03_b]1"thousand"c_jQT3   
                                                                                                                                jQT    Get digits of Q
                                                                                                                               _       Reverse
                                                                                                                              c    3   Split into groups of 3
  .e                                                                                                                                   Map the above, element as b, index as k, using:
                                                                                                                _b                       Reverse the digits in the group
                                                                                                            .[03                         Pad the above on the left with 0 to length 3
                                                                                                           c      ]1                     Chop at index 1 - [1,2,3] => [[1],[2,3]]
        .e                                                                                                                               Map the above, element as Z, index as Y, using:
          ?Y                                                                                                                               If second element in the group (i.e. tens and units):
            ?thZ                                                                                                                             If (tens - 1) is non-zero (i.e. 0 or >=2):
                   ?hZ                                                                                                                         If tens is non-zero:
                       @KhZ                                                                                                                      Lookup in tens names
                      +    "ty"                                                                                                                  Append "ty"
                                                                                                                                               Else:
                               ""                                                                                                                Empty string
                  ,                                                                                                                            Create two-element list of the above with...
                                 @JeZ                                                                                                          ... lookup units name
                jd                                                                                                                             Join the above on a space - this covers [0-9] and [20-99]
                                                                                                                                             Else:
                                                                     c"thir four"d                                                             ["thir", "four"]
                                                                    +             >K5                                                          Append last 5 element of tens names ("fif" onwards)
                                                            +R"teen"                                                                           Append "teen" to each string in the above
                                      +c"ten eleven twelve"d                                                                                   Prepend ["ten", "eleven", "twelve"]
                                     @                                               eZ                                                        Take string at index of units column - this covers [10-19]
                                                                                                                                           Else: (i.e. hundreds column)
                                                                                       ?hZ                                                   If hundreds column is non-zero:
                                                                                           @JhZ                                                Lookup units name
                                                                                          +    " hundred"                                      Append " hundred"
                                                                                                         ""                                  Else: empty string
                                                                                                                                         Result of map is two element list of [hundreds name, tens and units name]
      Wk                                                                                                                                 If k is nonzero (i.e. dealing with thousands group)...
     +                                                                                                              "thousand"           ... Append "thousand"
    y                                                                                                                                    Apply output formatting (join on spaces, strip, deduplicate spaces)
                                                                                                                                       Result of map is [units group string, thousands group string]
 _                                                                                                                                     Reverse group ordering to put thousands back in front
y                                                                                                                                      Apply output formatting again, implicit print
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.