Umwandlung von ganzen Zahlen in englische Wörter

21

Das Ziel dieses Codegolfs ist es, ganze Zahlen in englische Wörter umzuwandeln.

Das Programm fordert zur Eingabe auf. Wenn diese Eingabe keine Ganzzahl ist, drucken Sie NaN. Wenn es sich um eine Ganzzahl handelt, konvertieren Sie sie in englische Wörter und drucken Sie diese Wörter aus. Minimale Eingabe: 0 (Null). Maximale Eingabe: 9000 (neuntausend).
Also, 5kehrt zurück five(Groß- / Kleinschreibung spielt keine Rolle) und 500kehrt zurück five hundredoder five-hundred(Striche spielen keine Rolle).

Einige andere Regeln:

Ein onevor hundredoder thousandist optional: one hundredist aber hundredauch richtig (wenn die Eingabe 100natürlich ist).

Das Wort andzum Beispiel in one hundred and forty fiveist auch optional.

Leerzeichen sind wichtig. Also, für 500, five-hundredoder five hundredist richtig, aber fivehundredist es nicht.

Viel Glück!

ProgramFOX
quelle
Hier gibt es eine ungelöste Antwort: rgagnon.com/javadetails/java-0426.html .
Diese Antwort in SO macht ähnliche Sachen, ist aber kein Code-Golf.
ST3

Antworten:

7

Perl 281 Bytes

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

Zeilenumbrüche für horizontale Vernunft hinzugefügt. Das obige kann interaktiv verwendet werden, oder indem ein Wert über stdin übergeben wird.

Funktioniert ordnungsgemäß für alle Ganzzahlwerte im Bereich [0, 19999] . Werte außerhalb dieses Bereichs weisen ein undefiniertes Verhalten auf. Nicht ganzzahlige Werte werden gegen Null gekürzt, und als solche werden nur Werte gemeldet, die wirklich nicht numerisch sind NaN.

Beispielnutzung:

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

Beispielausgabe:

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
quelle
"1000000000: Tausend"? Und sollte 17.2 nicht "NaN" ausgeben?
DavidC
5
@DavidCarraher "... Werte außerhalb dieses Bereichs weisen ein undefiniertes Verhalten auf . Nicht ganzzahlige Werte werden gegen Null abgeschnitten.NaN
Primo
Da ich kein Perl-Experte bin, stelle ich folgende Frage: Fordert dieses Programm zur Eingabe auf?
ProgramFOX
@ProgramFOX Ich habe es aktualisiert, um einen Wert aus stdin zu lesen (wenn es interaktiv ausgeführt wird, fordert es den Benutzer zur Eingabe eines Werts auf), anstatt als Funktion.
Primo
13

JavaScript (375)

Wahrscheinlich ein schrecklicher Versuch, aber auf jeden Fall, hier geht ...

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

Hübsch gedruckt (als Funktion):

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
}

Beispielkonvertierung (beachte, dass sie sogar NaNaußerhalb der Grenzen ausgibt , dh ungültige Eingaben):

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
quelle
+1In einer Sprache wie Javascript ist es ziemlich schwierig, es besser zu machen. (Sie können das Leerzeichen entfernen N(s,z) {return, um 1 Zeichen zu sparen)
Math Chiller
Oh, haha, das muss ich verpasst haben. Ich habe anscheinend auch ein paar Zeichen in der OSaite verpasst . Ich werde das beheben ..
FireFly
11

Mathematica 60 57

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

Verwendung:

f[500]

fünfhundert

Bearbeiten:

InputString[]~WolframAlpha~{{"NumberName", 1}, "Plaintext"}
Alephalpha
quelle
3
Dies beantwortet die Frage nicht wirklich. Ich sagte, dass der Benutzer eine Nummer eingeben muss (z. B. über die Befehlszeile oder ein Eingabeaufforderungsfeld), und dann sollte Ihr Programm die Wörter ausgeben (z. B. in der Befehlszeile oder in einem Meldungsfeld). Ihr Code ist nur eine Funktion zum Konvertieren, und Ihr Programm fordert Sie nicht zur Eingabe auf.
ProgramFOX
@ProgramFOX heißt es "Der Benutzer gibt etwas ein". Dies bedeutet nicht, dass das Programm zur Eingabe auffordert.
MrZander
@ MrZander: Nun, "Das Programm fordert zur Eingabe auf" war eigentlich das, was ich meinte. Ich aktualisiere meine Frage, aber es wäre natürlich unfair, wenn ich die Antwort von alephalpha nicht positiv stimmen würde, also bekam er mein +1
ProgramFOX
8

Lisp, 72 56 Zeichen

Ich stelle fest, 1) dass dies alt ist und 2) dass es vollständig auf der Standardbibliothek beruht, um zu funktionieren, aber die Tatsache, dass Sie das c-lisp-Drucksystem dazu bringen können, solche Dinge zu tun, hat mich immer beeindruckt. Dabei wird auch die Eingabe eines Benutzers übernommen, konvertiert und gedruckt.

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

Es umfasst 72 Zeichen.

  • :junk-allowed Bewirkt, dass parse-integer bei einem Fehler nil zurückgibt, anstatt einen Fehler auszulösen.
  • ~:[if-nil~;if-non-nill] Bedingt auf Null vorausgesetzt, behandelt NaN wo nötig
  • ~:* Sichert die Argumentinterpretation, um die Eingabe erneut zu verarbeiten
  • ~r druckt die Zahl wie gewünscht als englische Wortfolge aus, außer mit vollständig korrigierter Interpunktion

Probe:

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

192hqfwoelkqhwef9812ho1289hg18hoif3h1o98g3hgq
NaN

Lisp-Info hauptsächlich von Practical Common Lisp .

Bearbeiten, richtig golfen bis zu 56 Zeichen

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

Diese Version funktioniert etwas anders. Anstatt eine Zeile zu lesen und zu konvertieren, ruft es den LISP-Reader auf, die Eingabe als LISP-S-Ausdruck zu interpretieren, versucht, sie als Zahl zu verwenden, und ignoriert sie, falls Fehler auftreten, und gibt nil zurück, um die Formatzeichenfolge mit Bedingungen zu versorgen. Dies ist vielleicht das erste Mal, dass ich gesehen habe, wie Lisp ein wirklich knappes Programm produziert hat ... Spaß!

  • (read) Ruft den Lisp-Reader / Parser auf, um einen Ausdruck aus der Standardeingabe zu lesen und in ein geeignetes Objekt zu konvertieren
  • (floor) Versuche, einen beliebigen numerischen Typ in die nächstniedrigere Ganzzahl umzuwandeln, führen bei nicht numerischen Typen zu einem Fehler
  • (ignore-errors ...) Wenn es das tut, was es sagt, fängt es alle Fehler im eingeschlossenen Ausdruck ab und ignoriert sie. Es gibt nil zurück, um den NaN-Zweig der Formatzeichenfolge einzugeben
Tom Scogland
quelle
Es ist sicher kein Problem, dass die Frage alt ist :) Ich habe deine Antwort so bearbeitet, dass der Name der Sprache und die Anzahl der Zeichen in einer Kopfzeile stehen.
ProgramFOX
Vielen Dank für die Änderungen. Ich habe die Stack * -Syntax für diese Dinge noch nicht festgelegt. Bin zurückgekommen und habe einen Fehler behoben, den ich auch bei der Beschreibung der Bedingung im Format String gemacht habe.
Tom Scogland
3

PHP, 327 310 308 Bytes

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

Nimmt die Zahl als Parameter und arbeitet für 0 <= n <= 12999

Nervenzusammenbruch

// 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
quelle
2

SAS, 70 Zeichen

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

Die Anweisungen windowund displayöffnen die SAS-Eingabeaufforderung. Die Eingabe für ngeht in Zeile 1. Dies nutzt das SAS-Format, words.das die Nummer als Wort oder Wortfolge mit "und", "" und "-" ausgibt.

Alex A.
quelle
2

PHP

777 Zeichen

Dies ist definitiv ein schrecklicher Versuch, aber Sie können mich nicht beschuldigen, Schlupflöcher ausgenutzt zu haben, und es ist eine sehr glückliche Zahl. Danke an ProgramFOX für den Tipp.

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

Lange Hand

<?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]];}
}
Gans
quelle
1
Ich denke , dass Sie Ihren Code durch die Schaffung von Arrays wie folgt verkürzen: array('zero','one','two').
ProgramFOX
@ProgramFOX oder sogar ['zero','one','two'](php 5.4+). Und wenn es Ihnen nichts ausmacht E_NOTICE, [zero,one,two]würde es auch funktionieren.
Primo
Ich sollte es aktualisieren, aber 777 ist so eine Glückszahl.
Gans
+1 für deine Bemühungen. PHP ist im Code-Golf auf tragische Weise unterrepräsentiert.
Primo
1

Python 2.x - 378

Die Ableitung von Fireflys antwortet, obwohl Psie rekursiv für jeden Bereich positiver Zahlen verwendet werden kann , indem sie auf Million oder Billionen usw. geändert wird. Dies unterstützt auch Werte bis zu 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())

Beispieltest (Eingabe ist <<<, Ausgabe ist >>>):

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

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

Obwohl, wenn jemand dieses seltsame "Buffer Underflow" -Problem erklären kann, wäre das großartig ...

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

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

quelle
print divmod(-2,1000) #-> (-1, 998)
Primo
Ja natürlich. Ich dachte, es könnte einen absoluten Wert haben oder so. Aber es gibt -1*1000und ein "Rest" von 998.
1

SmileBASIC, 365 dreihundertsiebenundvierzig Bytes

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

Es gibt ein Leerzeichen am Ende, wenn die letzten ein oder zwei Ziffern 0 sind.

12Me21
quelle
0

MOO - 55 Zeichen

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

Oder, wenn ich nicht auf "stdout" drucken muss - 42 Zeichen: $string_utils:english_number(read(player))

Hinweis: Dieser Code druckt keine Eingabeaufforderung an die Standardausgabe und druckt zero stattdessenNaN wenn die Eingabe keine Zahl ist.

Als Bonus kann dieser Code mit jeder Zahl innerhalb der Grenzen der MOO-Sprache ( 2147483647- -2147483648) umgehen .

Pfeffer
quelle
0

Wolfram-Sprache 27 40 Bytes

Die Nutzung der nativen Funktion IntegerName,

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

Das obige fordert zur Eingabe durch den Benutzer auf. Die vorliegende Implementierung gibt "NaN" zurück, wenn der Benutzer etwas anderes als eine ganze Zahl eingibt.


Einige Beispiele (mit voreingestellten Eingängen) :

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

zweihundertdreiundvierzig


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

eine Milliarde, zweihundertvierunddreißig Millionen, fünfhundertsiebenundsechzigtausend, achthundertneunzig


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

NaN

DavidC
quelle
0

Python 2 , 333 Bytes

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

Probieren Sie es online!

Dies gilt für 1 bis einschließlich 999.999.

Chas Brown
quelle
0

Pyth, 239 242 Bytes

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

Die Eingabe ist eine Ganzzahl im Bereich [0-999.999]. Probieren Sie es online aus hier aus . Erklärung ausstehend.

Vorherige Version, sehr ähnliche Operation, unterstützt aber nicht 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

Erklärung der Vorgängerversion:

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
quelle