Mengkonversi bilangan bulat ke kata-kata bahasa Inggris

21

Tujuan golf kode ini adalah untuk mengkonversi bilangan bulat menjadi kata-kata bahasa Inggris.

Program meminta input. Jika input ini bukan bilangan bulat, cetak NaN. Jika bilangan bulat, konversikan ke kata-kata bahasa Inggris dan cetak kata-kata ini. Input minimum: 0 (nol). Input maksimum: 9000 (sembilan ribu).
Jadi, 5return five(case tidak masalah), dan 500return five hundredatau five-hundred(strip tidak masalah).

Beberapa aturan lain:

A onesebelum hundredatau thousandopsional: one hundredbenar, tetapi hundredjuga (jika inputnya 100tentu saja).

Kata anddalam misalnya one hundred and forty fivejuga opsional.

Ruang putih penting. Jadi, untuk 500, five-hundredatau five hundredbenar, tetapi fivehundredtidak.

Semoga berhasil!

ProgramFOX
sumber
Ada jawaban yang tidak diklik di sini rgagnon.com/javadetails/java-0426.html .
Jawaban ini dalam SO melakukan hal serupa tetapi bukan kode-golf.
ST3

Jawaban:

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

Baris baru ditambahkan untuk kewarasan horisontal. Di atas dapat digunakan secara interaktif, atau dengan memberikan nilai melalui stdin.

Bekerja dengan benar untuk semua nilai integer pada rentang [0, 19999] , nilai di luar rentang ini menunjukkan perilaku yang tidak ditentukan. Nilai-nilai non-integer akan terpotong ke nol, dan dengan demikian, hanya nilai-nilai yang benar-benar non-numerik yang akan dilaporkan NaN.

Penggunaan sampel:

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

Output sampel:

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
primo
sumber
"1000000000: Ribu"? Dan bukankah seharusnya 17,2 mencetak "NaN"?
DavidC
5
@DavidCarraher "... nilai di luar rentang ini menunjukkan perilaku yang tidak terdefinisi . Nilai non-integer akan terpotong ke nol, dan dengan demikian, hanya nilai yang benar-benar non-numerik yang akan dilaporkan NaN."
Primo
Saya bukan ahli Perl, jadi saya mengajukan pertanyaan ini: apakah program ini meminta input?
ProgramFOX
@ProgramFOX Saya telah memperbaruinya untuk membaca nilai dari stdin (jika dijalankan secara interaktif, itu akan meminta pengguna untuk nilai), bukan sebagai fungsi.
Primo
13

JavaScript (375)

Mungkin upaya yang mengerikan, tapi toh, begini ...

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()))

Cukup dicetak (sebagai fungsi):

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
}

Konversi sampel (perhatikan bahwa output bahkan NaNkeluar di luar batas, yaitu input yang tidak valid):

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
FireFly
sumber
+1itu cukup sulit untuk dilakukan lebih baik dalam bahasa seperti javascript. (Anda dapat menghapus ruang N(s,z) {returnuntuk menghemat 1 char)
Math chiller
Oh, haha, pasti melewatkan yang itu. Saya juga tampaknya telah melewatkan banyak karakter di Otali. Saya akan memperbaikinya ..
FireFly
11

Mathematica 60 57

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

Pemakaian:

f[500]

lima ratus

Edit:

InputString[]~WolframAlpha~{{"NumberName", 1}, "Plaintext"}
alephalpha
sumber
3
Ini tidak benar-benar menjawab pertanyaan. Saya mengatakan bahwa pengguna harus memasukkan nomor (menggunakan baris perintah, atau kotak prompt misalnya), dan kemudian program Anda harus menampilkan kata-kata (pada baris perintah, atau dalam kotak pesan misalnya). Kode Anda hanya fungsi untuk mengubahnya, dan program Anda tidak meminta input.
ProgramFOX
@ProgramFOX dikatakan 'Pengguna memasukkan sesuatu'. Itu tidak berarti 'Program meminta input'.
MrZander
@ MrZander: Ya, 'Program meminta input' sebenarnya yang saya maksud. Saya memperbarui pertanyaan saya, tetapi tentu saja, itu tidak adil jika saya tidak akan menjawab jawaban alephalpha, jadi dia mendapatkan +1 saya
ProgramFOX
8

Lisp, 72 56 karakter

Saya menyadari 1) bahwa ini sudah tua, dan 2) bahwa ia sepenuhnya bergantung pada perpustakaan standar untuk berfungsi, tetapi kenyataan bahwa Anda dapat membuat sistem pencetakan c-lisp untuk melakukan hal semacam ini selalu membuat saya terkesan. Juga, ini sebenarnya mengambil input dari pengguna, mengubahnya, dan mencetaknya.

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

Totalnya 72 karakter.

  • :junk-allowed menyebabkan parse-integer mengembalikan nol pada kegagalan alih-alih meningkatkan kesalahan.
  • ~:[if-nil~;if-non-nill] bersyarat didasarkan pada nihil, menangani NaN bila perlu
  • ~:* mendukung interpretasi argumen untuk mengkonsumsi kembali input
  • ~r mencetak nomor sebagai string kata bahasa Inggris, seperti yang diminta, kecuali dengan tanda baca yang benar

Mencicipi:

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

192hqfwoelkqhwef9812ho1289hg18hoif3h1o98g3hgq
NaN

Info Lisp terutama dari Practical Common Lisp .

Edit, golf dengan baik hingga 56 karakter

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

Versi ini bekerja agak berbeda. Alih-alih membaca baris dan mengonversinya, ia meminta pembaca lisp untuk menginterpretasikan input sebagai ekspresi-lisp, mencoba menggunakannya sebagai angka, dan jika ada kesalahan yang dihasilkan, mengabaikannya menghasilkan nihil untuk memberi makan string format bersyarat. Ini mungkin contoh pertama yang saya lihat tentang program pembuatan program yang benar-benar singkat ... Menyenangkan!

  • (read) Meminta pembaca lisp / pengurai untuk membaca satu ekspresi dari input standar dan mengubahnya menjadi objek yang sesuai
  • (floor) mencoba mengubah tipe numerik apa pun menjadi bilangan bulat rendah terdekat, tipe non-numerik menyebabkannya menimbulkan kesalahan
  • (ignore-errors ...) melakukan apa yang tertulis di kaleng, menangkap dan mengabaikan kesalahan apa pun dalam ekspresi terlampir, mengembalikan nol untuk memberi makan cabang NaN dari string format
Tom Scogland
sumber
Sudah pasti tidak ada masalah bahwa pertanyaan lama :) Saya mengedit jawaban Anda untuk memasukkan nama bahasa dan jumlah karakter dalam sebuah tajuk.
ProgramFOX
Terima kasih atas hasil editnya, saya belum mendapatkan sintaks Stack * untuk semua ini. Kembali dan memperbaiki kesalahan yang saya buat dalam deskripsi kondisional dalam format string juga.
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;

mengambil angka sebagai parameter, berfungsi untuk 0 <= n <= 12999

kerusakan

// 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
;
Titus
sumber
2

SAS, 70 karakter

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

The windowdan displaypernyataan membuka SAS command prompt. Input untuk ngo on line 1. Ini mengambil keuntungan dari format SAS words.yang akan mencetak angka sebagai kata atau serangkaian kata dengan "dan", "", dan "-" yang sesuai.

Alex A.
sumber
2

PHP

777 karakter

Ini jelas merupakan upaya yang mengerikan, tetapi Anda tidak dapat menuduh saya memanfaatkan celah apa pun, ditambah lagi itu adalah angka yang sangat beruntung. Terima kasih kepada ProgramFOX untuk tipnya.

<?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]];}}

Tangan panjang

<?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]];}
}
Angsa
sumber
1
Saya pikir Anda dapat mempersingkat kode Anda dengan menciptakan array seperti ini: array('zero','one','two').
ProgramFOX
@ProgramFOX atau genap ['zero','one','two'](php 5.4+). Dan jika Anda tidak keberatan E_NOTICE, [zero,one,two]akan berhasil juga.
primo
Saya harus memperbaruinya, tetapi 777 adalah angka keberuntungan.
Angsa
+1 untuk upaya Anda. PHP secara tragis kurang terwakili dalam kode golf.
primo
1

Python 2.x - 378

Derivatif jawaban Fireflys, meskipun dengan mengubah Puntuk memasukkan jutaan atau triliunan, dll. Dapat secara rekursif digunakan untuk berbagai angka positif. Ini juga mendukung nilai hingga 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())

Uji sampel (input adalah <<<, output >>>):

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

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

Meskipun, jika seseorang dapat menjelaskan masalah "buffer underflow" aneh yang saya miliki, itu akan membengkak ...

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

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

sumber
print divmod(-2,1000) #-> (-1, 998)
Primo
Oh tentu. Saya berpikir mungkin butuh nilai absolut atau sesuatu. Tapi ada -1*1000dan "sisa" dari 998.
1

SmileBASIC, 365 Tiga Ratus Empat Puluh Tujuh 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

Ada spasi tambahan jika satu atau dua digit terakhir adalah 0.

12Me21
sumber
0

MOO - 55 karakter

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

Atau, jika saya tidak perlu mencetak ke "stdout" - 42 karakter: $string_utils:english_number(read(player))

Catatan: kode ini tidak mencetak prompt apa pun ke output standar dan mencetak zerobukannya NaNsaat input bukan angka.

Sebagai bonus, kode ini dapat menangani nomor apa pun dalam batasan bahasa moo ( 2147483647- -2147483648).

pppery
sumber
0

Bahasa Wolfram 27 40 byte

Memanfaatkan fungsi asli IntegerName,,

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

Di atas meminta input pengguna. Implementasi saat ini mengembalikan "NaN" jika pengguna memasukkan apa pun selain bilangan bulat.


Beberapa contoh (dengan input yang telah ditetapkan sebelumnya) :

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

dua ratus empat puluh tiga


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

satu miliar, dua ratus tiga puluh empat juta, lima ratus enam puluh tujuh ribu delapan ratus sembilan puluh


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

NaN

DavidC
sumber
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)))

Cobalah online!

Ini bagus untuk 1 hingga 999.999, inklusif.

Chas Brown
sumber
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

Input adalah bilangan bulat dalam rentang [0-999.999]. Cobalah online di sini . Penjelasan tertunda.

Versi sebelumnya, operasi yang sangat mirip, tetapi tidak mendukung 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

Penjelasan dari versi sebelumnya:

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
Sok
sumber