将整数转换为英语单词


21

该代码高尔夫的目标是将整数转换为英语单词。

程序提示输入。如果此输入不是整数,请打印NaN。如果是整数,请将其转换为英语单词并打印这些单词。最小输入:0(零)。最大输入:9000(九万)。
因此,5返回five(大小写无关紧要),以及500返回five hundredfive-hundred(破折号无关紧要)。

其他一些规则:

一个one之前hundred或者thousand是可选的:one hundred是正确的,但hundred太(如果输入的是100当然的)。

and例如,单词中的单词one hundred and forty five也是可选的。

空格很重要。所以,对500five-hundred或者five hundred是正确的,但fivehundred并非如此。

祝好运!


在这里rgagnon.com/javadetails/java-0426.html中有一个没有答案的答案。

SO中的这个答案做了类似的事情,但不是代码高尔夫。
2013年

Answers:


7

Perl 281字节

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

添加换行符以保持水平。可以交互使用上述内容,也可以通过stdin将其传递给值。

对于[0,19999]范围内的所有整数值均可正常工作,超出此范围的值表现出未定义的行为。非整数值将被截断为零,因此,只有真正非数字的值才会报告NaN

用法示例:

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

样本输出:

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:千”?并且17.2不应该打印“ NaN”吗?
DavidC

5
@DavidCarraher “ ...超出此范围的值表现出不确定的行为。非整数值将被截断为零,因此,只有真正非数字的值才会报告NaN。”
2013年

我不是Perl专家,所以我问这个问题:该程序是否提示输入?
ProgramFOX

@ProgramFOX我已经对其进行了更新,以从stdin读取值(如果以交互方式运行,它将提示用户输入值),而不是作为函数。
primo的

13

的JavaScript(375)

可能是一次可怕的尝试,但无论如何,这里...

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

精美印刷(作为功能):

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
}

样本转换(请注意,它甚至会NaN在超出范围时输出,即无效输入):

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

+1用javascript之类的语言来做更好的工作相当困难。(您可以删除其中的空间N(s,z) {return以节省1个字符)
Math chiller

哦,哈哈,一定错过了那个。我似乎也错过了O字符串中的许多字符。我会解决的..
FireFly

11

Mathematica 60 57

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

用法:

f[500]

五百

编辑:

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

3
这并不能真正回答问题。我说过用户必须输入一个数字(例如,使用命令行或提示框),然后您的程序应输出单词(例如,在命令行或消息框中)。您的代码只是一个将其转换的函数,您的程序不要求输入。
ProgramFOX 2013年

@ProgramFOX表示“用户输入了某些内容”。这并不意味着“程序提示输入”。
MrZander

@MrZander:嗯,“程序提示输入”实际上就是我的意思。我更新了我的问题,但是,如果我不反对alephalpha的答案,那当然是不公平的,所以他得到了我的+1
ProgramFOX

8

Lisp,72个 56个字符

我意识到1)这已经很老了,2)它完全依赖于标准库来运行,但是您可以使用c-lisp打印系统来执行这种操作这一事实一直令我印象深刻。而且,实际上,这确实从用户那里获取了输入,将其转换并打印出来。

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

总共72个字符。

  • :junk-allowed 使失败的parse-integer返回nil而不是引发错误。
  • ~:[if-nil~;if-non-nill] 以nil为条件的谓词,必要时处理NaN
  • ~:* 备份参数解释以重新使用输入
  • ~r 根据要求,将数字打印为英文单词字符串,但带有完整的标点符号除外

样品:

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

192hqfwoelkqhwef9812ho1289hg18hoif3h1o98g3hgq
NaN

Lisp信息主要来自实用Common Lisp

编辑,正确打低至56个字符

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

此版本的工作方式大不相同。它不读取行并将其转换,而是调用lisp阅读器将输入解释为lisp s表达式,尝试将其用作数字,并且如果产生任何错误,将忽略它们,产生nil以有条件地提供格式字符串。这可能是我第一次看到Lisp生成一个真正简洁的程序……好玩!

  • (read) 调用lisp阅读器/解析器以从标准输入中读取一个表达式并将其转换为适当的对象
  • (floor) 尝试将任何数字类型转换为最接近的较低整数,非数字类型导致它引发错误
  • (ignore-errors ...) 做到了如上所说,它捕获并忽略了所包含表达式中的任何错误,返回nil以提供格式字符串的NaN分支

老问题肯定没问题:)我编辑了您的答案,在标题中包含了语言名称和字符数。
ProgramFOX

谢谢您所做的编辑,我还没有掌握Stack *语法。返回并修复了我在条件字符串格式说明中所犯的一个错误。
汤姆·斯科格兰

3

PHP,327个 310 308字节

<?$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;

以数字为参数,适用于0 <= n <= 12999

分解

// 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个字符

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

windowdisplay语句开拓SAS命令提示符。输入n第1行。这利用了SAS格式words.,该格式将数字打印为一个单词或一系列单词,并带有“和”,“”和“-”。


2

的PHP

777个字符

这绝对是一次可怕的尝试,但是您不能指责我利用任何漏洞,而且这是一个非常幸运的数字。感谢ProgramFOX的技巧。

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

长手

<?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
我想你可以通过创建类似这样的阵列缩短你的代码:array('zero','one','two')
ProgramFOX 2015年

@ProgramFOX甚至['zero','one','two'](php 5.4+)。而且,如果您不介意E_NOTICE[zero,one,two]也可以。
2015年

我应该更新它,但是777是一个幸运的数字。
2015年

为您的努力+1。可悲的是,PHP在代码高尔夫领域的代表性不足。
2015年

1

Python 2.x-378

萤火虫的导数回答,尽管可以更改P为包括百万或万亿等,但它可以递归用于任何范围的正数。这也支持高达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())

样本测试(输入为<<<,输出为>>>):

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

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

虽然,如果有人可以解释我遇到的这个奇怪的“缓冲区下溢”问题,那将会很不错...

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

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

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

哦当然了 我当时在想这可能需要绝对的价值。但是还有-1*1000一个“余数” 998

1

SmileBASIC,365个三百四十七个字节

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

如果最后一位或两位数字为0,则存在一个尾随空格。


0

MOO -55个字符

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

或者,如果我不需要打印到“ stdout”-42个字符: $string_utils:english_number(read(player))

注意:此代码不会在标准输出中显示任何提示,zero而是NaN在输入不是数字时打印。

另外,此代码可以处理moo语言(2147483647- -2147483648)范围内的任何数字。


0

Wolfram语言 27 40字节

利用本机功能IntegerName

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

以上提示用户输入。如果用户输入的不是整数,则本实现返回“ NaN”。


一些示例(带有预设输入)

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

243


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

十亿,二十三亿四千四百万,五十六万七千,八十九万


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

N


0

Python 2 2,333字节

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

在线尝试!

这对于1到999,999(含1和999)之间的值是有利的。


0

Pyth,239 242个字节

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

输入是[0-999,999]范围内的整数。在线尝试在这里。说明待处理。

以前的版本,操作非常相似,但不支持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

先前版本的说明:

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.