Code Golf: nombre de mots
la série de golf de code semble être assez populaire. J'ai trouvé un code qui convertit un nombre en ses mots. Quelques exemples seraient (pouvoirs de 2 pour le plaisir de programmation):
- 2 - > Deux
- 1024 -> Mille Vingt-Quatre
- 1048576 -> Un Million Quarante Huit Mille Cinq Cent Soixante-Seize
l'algorithme que mon collègue a trouvé était presque deux cents lignes de long. Semble qu'il y aurait une manière plus concise de le faire.
lignes directrices actuelles:
- Soumissions en tout programmation langue de bienvenue (je m'excuse auprès de PhiLho pour le manque initial de clarté sur celui-ci)
- entrée Max de 2^64 (voir le lien suivant pour les mots, merci mmeyers)
- Courte échelle avec l'anglais de sortie préféré, mais tout l'algorithme est la bienvenue. Il suffit de commenter avec le langage de programmation quant à la méthode utilisée.
22 réponses
Lisp, utilisant uniquement des fonctions standard:
(format nil "~r" 1234) ==> "one thousand two hundred thirty-four"
Bonus:
(format nil "~@r" 1234) ==> "MCCXXXIV"
Ok, je pense qu'il est temps pour mon propre implémentation dans le script Windows BATCH (devrait fonctionner sur Windows 2000 ou plus tard).
voici le code:
@echo off
set zero_to_nineteen=Zero One Two Three Four Five Six Seven Eight Nine Ten Eleven Twelve Thirteen Fourteen Fifteen Sixteen Seventeen Eighteen Nineteen
set twenty_to_ninety=ignore ignore Twenty Thirty Forty Fifty Sixty Seventy Eighty Ninety
set big_numbers=ignore Thousand Million Billion Trillion Quadrillion Quintillion Sextillion Septillion Octillion Nonillion Decillion Undecillion Duodecillion Tredecillion Quattuordecillion Quindecillion Sexdecillion Septendecillion Octodecillion Novemdecillion Vigintillion
rem 10^0 10^3 10^6 10^9 10^12 10^15 10^18 10^21 10^24 10^27 10^30 10^33 10^36 10^39 10^42 10^45 10^48 10^51 10^54 10^57 10^60 10^63
call :parse_numbers %*
exit /B 0
:parse_numbers
:parse_numbers_loop
if "$%~1" == "$" goto parse_numbers_end
call :parse_number %~1
echo %~1 -^> %parse_number_result%
shift
goto parse_numbers_loop
:parse_numbers_end
exit /B 0
:parse_number
call :get_sign %~1
set number_sign=%get_sign_result%
call :remove_groups %get_sign_result_number%
call :trim_leading_zeros %remove_groups_result%
set number=%trim_leading_zeros_result%
if "$%number%" == ""151900920"" (
set parse_number_result=Zero
exit /B 0
)
set counter=0
set parse_number_result=
:parse_number_loop
set last_three=%number:~-3%
set number=%number:~0,-3%
call :parse_three %last_three%
call :get_from %counter% %big_numbers%
if "$%get_from_result%" == "$" (
set parse_number_result=* ERR: the number is too big! Even wikipedia doesn't know how it's called!
exit /B 0
)
if not "$%parse_three_result%" == "$Zero" (
if %counter% == 0 (
set parse_number_result=%parse_three_result%
) else (
if not "$%parse_number_result%" == "$" (
set parse_number_result=%parse_three_result% %get_from_result% %parse_number_result%
) else (
set parse_number_result=%parse_three_result% %get_from_result%
)
)
)
set /A counter+=1
if not "$%number%" == "$" goto parse_number_loop
if "$%parse_number_result%" == "$" (
set parse_number_result=Zero
exit /B 0
) else if not "$%number_sign%" == "$" (
set parse_number_result=%number_sign% %parse_number_result%
)
exit /B 0
:parse_three
call :trim_leading_zeros %~1
set three=%trim_leading_zeros_result%
set /A three=%three% %% 1000
set /A two=%three% %% 100
call :parse_two %two%
set parse_three_result=
set /A digit=%three% / 100
if not "$%digit%" == ""151900920"" (
call :get_from %digit% %zero_to_nineteen%
)
if not "$%digit%" == ""151900920"" (
if not "$%get_from_result%" == "$Zero" (
set parse_three_result=%get_from_result% Hundred
)
)
if "$%parse_two_result%" == "$Zero" (
if "$%parse_three_result%" == "$" (
set parse_three_result=Zero
)
) else (
if "$%parse_three_result%" == "$" (
set parse_three_result=%parse_two_result%
) else (
set parse_three_result=%parse_three_result% %parse_two_result%
)
)
exit /B 0
:parse_two
call :trim_leading_zeros %~1
set two=%trim_leading_zeros_result%
set /A two=%two% %% 100
call :get_from %two% %zero_to_nineteen%
if not "$%get_from_result%" == "$" (
set parse_two_result=%get_from_result%
goto parse_two_20_end
)
set /A digit=%two% %% 10
call :get_from %digit% %zero_to_nineteen%
set parse_two_result=%get_from_result%
set /A digit=%two% / 10
call :get_from %digit% %twenty_to_ninety%
if not "$%parse_two_result%" == "$Zero" (
set parse_two_result=%get_from_result% %parse_two_result%
) else (
set parse_two_result=%get_from_result%
)
goto parse_two_20_end
:parse_two_20_end
exit /B 0
:get_from
call :trim_leading_zeros %~1
set idx=%trim_leading_zeros_result%
set /A idx=0+%~1
shift
:get_from_loop
if "$%idx%" == ""151900920"" goto get_from_loop_end
set /A idx-=1
shift
goto get_from_loop
:get_from_loop_end
set get_from_result=%~1
exit /B 0
:trim_leading_zeros
set str=%~1
set trim_leading_zeros_result=
:trim_leading_zeros_loop
if not "$%str:~0,1%" == ""151900920"" (
set trim_leading_zeros_result=%trim_leading_zeros_result%%str%
exit /B 0
)
set str=%str:~1%
if not "$%str%" == "$" goto trim_leading_zeros_loop
if "$%trim_leading_zeros_result%" == "$" set trim_leading_zeros_result=0
exit /B 0
:get_sign
set str=%~1
set sign=%str:~0,1%
set get_sign_result=
if "$%sign%" == "$-" (
set get_sign_result=Minus
set get_sign_result_number=%str:~1%
) else if "$%sign%" == "$+" (
set get_sign_result_number=%str:~1%
) else (
set get_sign_result_number=%str%
)
exit /B 0
:remove_groups
set str=%~1
set remove_groups_result=%str:'=%
exit /B 0
C'est le script de test que j'ai utilisé:
@echo off
rem 10^x:x= 66 63 60 57 54 51 48 45 42 39 36 33 30 27 24 21 18 15 12 9 6 3 0
call number 0
call number 2
call number -17
call number 30
call number 48
call number -256
call number 500
call number 874
call number 1'024
call number -17'001
call number 999'999
call number 1'048'576
call number -1'000'001'000'000
call number 912'345'014'587'957'003
call number -999'912'345'014'587'124'337'999'999
call number 111'222'333'444'555'666'777'888'999'000'000'000'001
call number -912'345'014'587'912'345'014'587'124'912'345'014'587'124'337
call number 999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999
call number 1'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000
rem 10^x:x= 66 63 60 57 54 51 48 45 42 39 36 33 30 27 24 21 18 15 12 9 6 3 0
et c'est la sortie que j'ai eu de mon script de test:
0 -> Zero
2 -> Two
-17 -> Minus Seventeen
30 -> Thirty
48 -> Forty Eight
-256 -> Minus Two Hundred Fifty Six
500 -> Five Hundred
874 -> Eight Hundred Seventy Four
1'024 -> One Thousand Twenty Four
-17'001 -> Minus Seventeen Thousand One
999'999 -> Nine Hundred Ninety Nine Thousand Nine Hundred Ninety Nine
1'048'576 -> One Million Forty Eight Thousand Five Hundred Seventy Six
-1'000'001'000'000 -> Minus One Trillion One Million
912'345'014'587'957'003 -> Nine Hundred Twelve Quadrillion Three Hundred Forty Five Trillion Fourteen Billion Five Hundred Eighty Seven Million Nine Hundred Fifty Seven Thousand Three
-999'912'345'014'587'124'337'999'999 -> Minus Nine Hundred Ninety Nine Septillion Nine Hundred Twelve Sextillion Three Hundred Forty Five Quintillion Fourteen Quadrillion Five Hundred Eighty Seven Trillion One Hundred Twenty Four Billion Three Hundred Thirty Seven Million Nine Hundred Ninety Nine Thousand Nine Hundred Ninety Nine
111'222'333'444'555'666'777'888'999'000'000'000'001 -> One Hundred Eleven Undecillion Two Hundred Twenty Two Decillion Three Hundred Thirty Three Nonillion Four Hundred Forty Four Octillion Five Hundred Fifty Five Septillion Six Hundred Sixty Six Sextillion Seven Hundred Seventy Seven Quintillion Eight Hundred Eighty Eight Quadrillion Nine Hundred Ninety Nine Trillion One
-912'345'014'587'912'345'014'587'124'912'345'014'587'124'337 -> Minus Nine Hundred Twelve Tredecillion Three Hundred Forty Five Duodecillion Fourteen Undecillion Five Hundred Eighty Seven Decillion Nine Hundred Twelve Nonillion Three Hundred Forty Five Octillion Fourteen Septillion Five Hundred Eighty Seven Sextillion One Hundred Twenty Four Quintillion Nine Hundred Twelve Quadrillion Three Hundred Forty Five Trillion Fourteen Billion Five Hundred Eighty Seven Million One Hundred Twenty Four Thousand Three Hundred Thirty Seven
999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999 -> Nine Hundred Ninety Nine Vigintillion Nine Hundred Ninety Nine Novemdecillion Nine Hundred Ninety Nine Octodecillion Nine Hundred Ninety Nine Septendecillion Nine Hundred Ninety Nine Sexdecillion Nine Hundred Ninety Nine Quindecillion Nine Hundred Ninety Nine Quattuordecillion Nine Hundred Ninety Nine Tredecillion Nine Hundred Ninety Nine Duodecillion Nine Hundred Ninety Nine Undecillion Nine Hundred Ninety Nine Decillion Nine Hundred Ninety Nine Nonillion Nine Hundred Ninety Nine Octillion Nine Hundred Ninety Nine Septillion Nine Hundred Ninety Nine Sextillion Nine Hundred Ninety Nine Quintillion Nine Hundred Ninety Nine Quadrillion Nine Hundred Ninety Nine Trillion Nine Hundred Ninety Nine Billion Nine Hundred Ninety Nine Million Nine Hundred Ninety Nine Thousand Nine Hundred Ninety Nine
1'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000 -> * ERR: the number is too big! Even wikipedia doesn't know how it's called!
si je pouvais en trouver d'autres noms de grands nombres , le script supporterait encore plus grand nombre. Actuellement, le script fonctionnera avec tous les nombres de -(10^66-1) à (10^66-1).
je dois mentionner, que j'ai eu beaucoup de plaisir à résoudre ce en fournée. :)
C# - 30 lines incl. déclaration de méthode et { }s :
tient compte de toutes les virgules, Andes et traits d'Union susmentionnés. J'ai seulement inclus jusqu'à l'octillion parce que décimal.MaxValue est seulement dans les octillons. Pour les entiers plus grands, vous auriez besoin d'ajouter des éléments correspondants au tableau thou[] et peut-être passer le nombre en tant que chaîne, en modifiant la ligne pour extraire le bloc en utilisant les 3 derniers caractères au lieu d'utiliser modulo comme je l'ai ici.
static string wordify(decimal v)
{
if (v == 0) return "zero";
var units = " one two three four five six seven eight nine".Split();
var teens = " eleven twelve thir# four# fif# six# seven# eigh# nine#".Replace("#", "teen").Split();
var tens = " ten twenty thirty forty fifty sixty seventy eighty ninety".Split();
var thou = " thousand m# b# tr# quadr# quint# sext# sept# oct#".Replace("#", "illion").Split();
var g = (v < 0) ? "minus " : "";
var w = "";
var p = 0;
v = Math.Abs(v);
while (v > 0)
{
int b = (int)(v % 1000);
if (b > 0)
{
var h = (b / 100);
var t = (b - h * 100) / 10;
var u = (b - h * 100 - t * 10);
var s = ((h > 0) ? units[h] + " hundred" + ((t > 0 | u > 0) ? " and " : "") : "")
+ ((t > 0) ? (t == 1 && u > 0) ? teens[u] : tens[t] + ((u > 0) ? "-" : "") : "")
+ ((t != 1) ? units[u] : "");
s = (((v > 1000) && (h == 0) && (p == 0)) ? " and " : (v > 1000) ? ", " : "") + s;
w = s + " " + thou[p] + w;
}
v = v / 1000;
p++;
}
return g + w;
}
appelé en utilisant:
static void Main(string[] args)
{
Console.WriteLine(wordify(decimal.MaxValue));
}
sortie:
soixante-dix-neuf octillion, deux cents et vingt-huit septillion, un cent soixante-deux sextillons, cinq cent quatorze quintillions, deux cent soixante-quatre quadrillions, trois cent trente-sept milliards de dollars, cinq cent quatre-vingt-treize milliards cinq cents et quarante-trois millions neuf cent cinquante mille trois cent trente-cinq
dans A86 assember - assembles à A. Com executable:
dd 0ba02c6bfh, 0b8bd10c1h, 0e808b512h, 0ea870100h, 08700e9e8h, 010273eah
dd 0e0e8c2h, 06b51872h, 0c000ebe8h, 0b3c02e8h, 03368067dh, 0b2e901h
dd 0baaa5004h, 0fd8110c1h, 0cd7c1630h, 0bf3031bbh, 0a0571000h, 0ec880080h
dd 0c581c589h, 023c0081h, 0e7f087ch, 0823e38h, 027b00875h, 0e901d068h
dd 0b6400080h, 04f6f603h, 080d08a1ch, 0b60f80c4h, 07f06c7f4h, 088303000h
dd 0ac00813eh, 087ef828h, 0b00056e8h, 051e81dh, 0d83850adh, 0e7f157ch
dd 0a74fc38h, 0262ce088h, 0e901a368h, 01d2c003bh, 0580036e8h, 0b7efc38h
dd 0774d838h, 0f828e088h, 0800026e8h, 0127e1dfah, 0afd448ah, 0440afe44h
dd 074f838ffh, 0e8c28a05h, 0cafe000fh, 0ab7cee39h, 05a2405c6h, 021cd09b4h
dd 05e856c3h, 020b05e00h, 0c5bec3aah, 074c00a02h, 03c80460ah, 0fefa755bh
dd 046f675c8h, 0745b3cach, 0f8ebaae8h, 0eec1d689h, 08a3c8a03h, 07e180cah
dd 0cfd2c1feh, 0ebe8c342h, 0fed8d0ffh, 0c3f775cdh, 01e581e8fh, 0303c5ea8h
dd 0df6f652ah, 078bde03ch, 05e027500h, 01ec1603ch, 07d40793dh, 0603c8080h
dd 09f6f2838h, 040f17a3dh, 080f17a22h, 0403d7264h, 0793cdee1h, 0140740f1h
dd 01e2f7d32h, 02f488948h, 0a7c43b05h, 0a257af9bh, 0be297b6ch, 04609e30ah
dd 0b8f902abh, 07c21e13eh, 09a077d9eh, 054f82ab5h, 0fabe2af3h, 08a6534cdh
dd 0d32b4c97h, 035c7c8ceh, 082bcc833h, 0f87f154fh, 0650ff7eah, 02f143fdfh
dd 0a1fd687fh, 0c3e687fdh, 0c6d50fe0h, 075f13574h, 0898c335bh, 0e748ce85h
dd 08769676fh, 0ad2cedd3h, 0928c77c7h, 077e2d18eh, 01a77e8f6h
db 0bah, 01bh
c'est un exécutable de 454 octets.
voici le code (légèrement plus petit). Puisque A86 est un 8086 seulement assembleur, j'ai dû code à la main les extensions 32bit:
mov di,strings
mov dx,tree_data * 8 + 1
mov bp,code_data * 8
l1:
mov ch,8
call extract_bits
xchg dx,bp
call extract_bit
xchg dx,bp
jnc l2
add dx,ax
l2:
call extract_bit
jc l3
mov ch,6
call extract_bits
shr al,2
cmp al,11
push l27
jl get_string
l25:
add al,48+32
stosb
l27:
mov dx,tree_data * 8 + 1
l3:
cmp bp,end_data * 8
jl l1
convert:
mov bx,'01'
mov di,01000h
push di
mov al,[80h]
mov ah,ch
mov bp,ax
add bp,81h
cmp al,2
jl zero
jg l90
cmp byte ptr [82h],bh
jne l90
zero:
mov al,39
push done
get_string:
mov si,strings-1
or al,al
je l36
l35:
inc si
cmp byte ptr [si],';'+32
jne l35
dec al
jnz l35
l36:
inc si
l37:
lodsb
cmp al,';'+32
je ret
stosb
jmp l37
l90:
inc ax
mov dh,3
div dh
add al,28
mov dl,al
add ah,80h
db 0fh, 0b6h, 0f4h ; movzx si,ah
mov word ptr [80h],'00'
l95:
lodsb
sub al,bh
jle l100
call get_string2
mov al,29
call get_string2
l100:
lodsw
push ax
cmp al,bl
jl l150
jg l140
cmp ah,bh
je l140
mov al,ah
sub al,'0'-10
push l150
get_string2:
push si
call get_string
pop si
mov al,' '
stosb
ret
l140:
sub al,'0'-19
call get_string2
l150:
pop ax
cmp ah,bh
jle l200
cmp al,bl
je l200
mov al,ah
sub al,bh
call get_string2
l200:
cmp dl,29
jle l300
mov al,[si-3]
or al,[si-2]
or al,[si-1]
cmp al,bh
je l300
mov al,dl
call get_string2
l300:
dec dl
cmp si,bp
jl l95
done:
mov byte ptr [di],'$'
pop dx
mov ah,9
int 21h
int 20h
l41:
rcr al,1
dec ch
jz ret
extract_bits:
push l41
extract_bit:
mov si,dx
shr si,3
mov bh,[si]
mov cl,dl
and cl,7
inc cl
ror bh,cl
inc dx
ret
tree_data:
dw 01e8fh, 01e58h, 05ea8h, 0303ch, 0652ah, 0df6fh, 0e03ch, 078bdh
dw 07500h, 05e02h, 0603ch, 01ec1h, 0793dh, 07d40h, 08080h, 0603ch
dw 02838h, 09f6fh, 07a3dh, 040f1h, 07a22h, 080f1h, 07264h, 0403dh
dw 0dee1h, 0793ch, 040f1h, 01407h, 07d32h, 01e2fh, 08948h
db 048h
code_data:
dw 052fh, 0c43bh, 09ba7h, 057afh, 06ca2h, 0297bh, 0abeh, 09e3h
dw 0ab46h, 0f902h, 03eb8h, 021e1h, 09e7ch, 077dh, 0b59ah, 0f82ah
dw 0f354h, 0be2ah, 0cdfah, 06534h, 0978ah, 02b4ch, 0ced3h, 0c7c8h
dw 03335h, 0bcc8h, 04f82h, 07f15h, 0eaf8h, 0ff7h, 0df65h, 0143fh
dw 07f2fh, 0fd68h, 0fda1h, 0e687h, 0e0c3h, 0d50fh, 074c6h, 0f135h
dw 05b75h, 08c33h, 08589h, 048ceh, 06fe7h, 06967h, 0d387h, 02cedh
dw 0c7adh, 08c77h, 08e92h, 0e2d1h, 0f677h, 077e8h, 0ba1ah
db 01bh
end_data:
strings:
le texte est stocké en utilisant L'encodage de Huffman. La ligne de commande est passée comme une chaîne de caractères donc la conversion est simple-diviser la chaîne en groupes de trois et analysez chaque groupe (centaines, dizaines et unités) en suivant chacun avec le multiplicateur courant (millions, milliers, etc).
C++, 15 lignes:
#include <string>
using namespace std;
string Thousands[] = { "zero", "thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sexillion", "septillion", "octillion", "nonillion", "decillion" };
string Ones[] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
string Tens[] = { "zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" };
string concat(bool cond1, string first, bool cond2, string second) { return (cond1 ? first : "") + (cond1 && cond2 ? " " : "") + (cond2 ? second : ""); }
string toStringBelowThousand(unsigned long long n) {
return concat(n >= 100, Ones[n / 100] + " hundred", n % 100 != 0, (n % 100 < 20 ? Ones[n % 100] : Tens[(n % 100) / 10] + (n % 10 > 0 ? " " + Ones[n % 10] : "")));
}
string toString(unsigned long long n, int push = 0) {
return n == 0 ? "zero" : concat(n >= 1000, toString(n / 1000, push + 1), n % 1000 != 0, concat(true, toStringBelowThousand(n % 1000), push > 0, Thousands[push]));
}
Utilisation:
cout << toString(51351); // => fifty one thousand three hundred fifty one
est-ce de la triche?
perl -MNumber::Spell -e 'print spell_number(2);'
Paul Fischer et Darius: vous avez de bonnes idées, mais je déteste les voir mises en œuvre d'une façon aussi verbeuse. :) Je plaisante, votre solution est géniale, mais j'ai pressé 14 30 octets de plus, tout en restant à l'intérieur de 79 colonnes et en maintenant la compatibilité python 3.
alors voici mon Python 416 octets en 79 colonnes: (merci les gars, je me tiens sur vos épaules)
w=lambda n:_(n,["","thousand "]+p("m b tr quadr quint","illion"))[:-1]or"zero"
_=lambda n,S:n*"x"and _(n//M,S[1:])+(Z[n%M//C]+"hundred ")*(n%M//C>0)+(n%C>19
and p("twen thir fo"+R,"ty")[n%C//10-2]+Z[n%10]or Z[n%C])+S[0]*(n%M>0)
p=lambda a,b="":[i+b+" "for i in a.split()]
R="r fif six seven eigh nine"
M=1000
C=100
Z=[""]+p("one two three four five%st nine ten eleven twelve"%R[5:20])+p(
"thir fou"+R,"teen")
et le essais:
if __name__ == "__main__":
import sys
assert(w(0)=="zero")
assert(w(100)=="one hundred")
assert(w(1000000)=="one million")
assert(w(1024)=="one thousand twenty four")
assert(w(1048576)=="one million forty eight thousand five hundred seventy six")
See recursiven's better answer. C'est la façon betterer.
Mad props Darius pour trouver de l'inspiration sur ce coup. Votre grand - W
(maintenant mon p
) était particulièrement intelligent.
w=lambda n:["zero"," ".join(_(n,0))][n>0]
_=lambda n,l:_(n//M,l+1)+[E,Z[n%M//C]+["hundred"]][n%M//C>0]+\
(p("twen thir fo"+R,"ty")[n%C//10-2]+Z[n%10]if n%C>19 else Z[n%C])+\
[E,([E,["thousand"]]+p("m b tr quadr quint","illion"))[l]][n%M>0]if n else E
p=lambda a,b:[[i+b]for i in a.split()]
E=[];R="r fif six seven eigh nine";M=1000;C=100
Z=[E]+p("one two three four five six seven eight nine ten eleven twelve","")+\
p("thir fou"+R,"teen")
je le teste avec ceci:
if __name__ == "__main__":
import sys
print w(int(sys.argv[1]))
assert(w(100)=="one hundred")
assert(w(1000000)=="one million")
assert(w(1024)=="one thousand twenty four")
assert(w(1048576)=="one million forty eight thousand five hundred seventy six")
à ce point, c'est un tweak de la solution actuelle de Darius, qui est à son tour un tweak de mon aîné, qui a été inspiré par le sien, et il a donné quelques conseils de bug dans les commentaires. C'est aussi un crime contre Python.
Spoilers below, rot13 ' D pour votre protection, parce que la moitié du plaisir de golf trouver comment. Je recommande vivement le Mnenhy Firefox extension pour décoder ceci (et d'autres schémas d'encodage simples) en ligne.
Pbafgnagf (V eranzrq gurz guvf erivfvba gb ubcrshyyl znxr gurz pyrnere.)
-
R
: Gur rzcgl frg. -
E
: Gung juvpu vf va pbzzba orgjrra pbhagvat va gur "grraf" ( e grra, svs grra, fvk grra...) naq va gur graf ( e gl, svs gl, FVK GL....) -
Z
,P
: Jung gurl ner va Ebzna ahzrenyf. -
M
: Nyy gur ahzoref sebz bar GB gjragl.
Shapgvbaf (fbzr nyfb eranzrq guvf ebhaq)
-
j
: Gur choyvp-snpvat shapgvba, juvpu gheaf n ahzore vagb jbeqf. -
_
: Erphefviryl gheaf gur ahzore vagb jbeqf, gubhfnaq-ol-gubhfnaq.a
vf gur ahzore,y
vf ubj sne guebhtu gur cbjref bs 1000 jr ner. Ergheaf n yvfg bs fvatyrgba yvfgf bs rnpu jbeq va gur ahzore, r.t.[['bar'],['gubhfnaq'],['gjragl'],['sbhe']]
. -
c
: sbe rnpu jbeq va gur fcnpr-frcnengrq jbeq yvfgn
, nccraqfo
nf n fhssvk naq chgf gurz rnpu vagb n fvatyrgba yvfg. Sbe rknzcyr,c("z o ge","vyyvba") == [['zvyyvba'],['ovyyvba'],['gevyyvba']]
.
Python, 446 octets. Toutes les lignes sous 80 colonnes, bon sang. C'est la solution de Paul Fisher avec des modifications de codage sur presque toutes les lignes, en bas de sa version de 488 octets; il a depuis pressé plusieurs octets supplémentaires, et je concède. Allez voter pour sa réponse!
g=lambda n:["zero"," ".join(w(n,0))][n>0]
w=lambda n,l:w(n//m,l+1)+[e,z[n%m//100]+["hundred"]][n%m//100>0]+\
(p("twen thir fo"+r,"ty")[n%100//10-2]+z[n%10]if n%100>19 else z[n%100])+\
[e,k[l]][n%m>0]if n else e
p=lambda a,b:[[i+b]for i in a.split()]
e=[];r="r fif six seven eigh nine";m=1000
k=[e,["thousand"]]+p("m b tr quadr quint","illion")
z=[e]+p("one two three four five six seven eight nine ten eleven twelve","")+\
p("thir fou"+r,"teen")
l'histoire s'est compliquée. J'ai commencé avec le code non masqué ci-dessous, qui prend en charge les nombres négatifs et le contrôle de portée, plus les tirets dans certains nombres pour mieux Anglais:
>>> n2w(2**20)
'one million forty-eight thousand five hundred seventy-six'
def n2w(n):
if n < 0: return 'minus ' + n2w(-n)
if n < 10: return W('zero one two three four five six seven eight nine')[n]
if n < 20: return W('ten eleven twelve',
'thir four fif six seven eigh nine',
'teen')[n-10]
if n < 100:
tens = W('', 'twen thir for fif six seven eigh nine', 'ty')[n//10-2]
return abut(tens, '-', n2w(n % 10))
if n < 1000:
return combine(n, 100, 'hundred')
for i, word in enumerate(W('thousand', 'm b tr quadr quint', 'illion')):
if n < 10**(3*(i+2)):
return combine(n, 10**(3*(i+1)), word)
assert False
def W(b, s='', suff=''): return b.split() + [s1 + suff for s1 in s.split()]
def combine(n, m, term): return abut(n2w(n // m) + ' ' + term, ' ', n2w(n % m))
def abut(w10, sep, w1): return w10 if w1 == 'zero' else w10 + sep + w1
alors je l'ai pressé à environ 540 octets via l'obscurcissement (nouveau pour moi), et Paul Fisher a trouvé un algorithme plus court (laissant tomber les tirets) avec quelques astuces de codage de Python merveilleusement horribles. J'ai volé les astuces de codage pour descendre à 508 (qui n'a toujours pas gagné). J'ai essayé de redémarrer fresh avec un nouvel algorithme, qui était incapable de battre celui de Fisher. Enfin voici le tweak de son code. Le Respect!
le code obscurci a été testé par rapport au code propre, qui a été vérifié par les yeux sur un tas de cas.
Ok, voici F#, essayant de rester lisible, à environ 830 octets:
#light
let thou=[|"";"thousand";"million";"billion";"trillion";"quadrillion";"quintillion"|]
let ones=[|"";"one";"two";"three";"four";"five";"six";"seven";"eight";"nine";"ten";"eleven";
"twelve";"thirteen";"fourteen";"fifteen";"sixteen";"seventeen";"eighteen";"nineteen"|]
let tens=[|"";"";"twenty";"thirty";"forty";"fifty";"sixty";"seventy";"eighty";"ninety"|]
let (^-) x y = if y="" then x else x^"-"^y
let (^+) x y = if y="" then x else x^" "^y
let (^?) x y = if x="" then x else x^+y
let (+^+) x y = if x="" then y else x^+y
let Tiny n = if n < 20 then ones.[n] else tens.[n/10] ^- ones.[n%10]
let Small n = (ones.[n/100] ^? "hundred") +^+ Tiny(n%100)
let rec Big n t = if n = 0UL then "" else
(Big (n/1000UL) (t+1)) +^+ (Small(n%1000UL|>int) ^? thou.[t])
let Convert n = if n = 0UL then "zero" else Big n 0
et voici les essais unitaires
let Show n =
printfn "%20u -> \"%s\"" n (Convert n)
let tinyTests = [0; 1; 10; 11; 19; 20; 21; 30; 99] |> List.map uint64
let smallTests = tinyTests @ (tinyTests |> List.map (fun n -> n + 200UL))
let MakeTests t1 t2 =
List.map (fun n -> n * (pown 1000UL t1)) smallTests
|> List.map_concat (fun n -> List.map (fun x -> x * (pown 1000UL t2) + n) smallTests)
for n in smallTests do
Show n
for n in MakeTests 1 0 do
Show n
for n in MakeTests 5 2 do
Show n
Show 1000001000678000001UL
Show 17999999999999999999UL
Voici une implémentation relativement simple en C (52 lignes).
NOTE : ceci n'effectue aucune vérification des limites; l'appelant doit s'assurer que le tampon d'appel est assez grand.
#include <stdio.h>
#include <string.h>
const char *zero_to_nineteen[20] = {"", "One ", "Two ", "Three ", "Four ", "Five ", "Six ", "Seven ", "Eight ", "Nine ", "Ten ", "Eleven ", "Twelve ", "Thirteen ", "Fourteen ", "Fifteen ", "Sixteen ", "Seventeen ", "Eighteen ", "Nineteen "};
const char *twenty_to_ninety[8] = {"Twenty ", "Thirty ", "Forty ", "Fifty ", "Sixty ", "Seventy ", "Eighty ", "Ninety "};
const char *big_numbers[7] = {"", "Thousand ", "Million ", "Billion ", "Trillion ", "Quadrillion ", "Quintillion "};
void num_to_word(char *buf, unsigned long long num)
{
unsigned long long power_of_1000 = 1000000000000000000ull;
int power_index = 6;
if(num == 0)
{
strcpy(buf, "Zero");
return;
}
buf[0] = 0;
while(power_of_1000 > 0)
{
int group = num / power_of_1000;
if(group >= 100)
{
strcat(buf, zero_to_nineteen[group / 100]);
strcat(buf, "Hundred ");
group %= 100;
}
if(group >= 20)
{
strcat(buf, twenty_to_ninety[group / 10 - 2]);
group %= 10;
}
if(group > 0)
strcat(buf, zero_to_nineteen[group]);
if(num >= power_of_1000)
strcat(buf, big_numbers[power_index]);
num %= power_of_1000;
power_of_1000 /= 1000;
power_index--;
}
buf[strlen(buf) - 1] = 0;
}
et voici une version beaucoup plus brouillée de cela (682 caractères). Il pourrait probablement être raboté un peu plus bas si j'ai vraiment essayé.
#include <string.h>
#define C strcat(b,
#define U unsigned long long
char*z[]={"","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nineteen"},*t[]={"Twenty ","Thirty ","Forty ","Fifty ","Sixty ","Seventy ","Eighty ","Ninety "},*q[]={"","Thousand ","Million ","Billion ","Trillion ","Quadrillion ","Quintillion "};
void W(char*b,U n){U p=1000000000000000000ull;int i=6;*b=0;if(!n)strcpy(b,"Zero ");else while(p){int g=n/p;if(g>99){C z[g/100]);C " ");C "Hundred ");g%=100;}if(g>19){C t[g/10-2]);g%=10;}if(g)C z[g]),C " ");if(n>=p)C q[i]);n%=p;p/=1000;i--;}b[strlen(b)-1]=0;}
une fonction T-SQL (SQL Server 2005), y compris les cas d'essai:
if exists (select 1 from sys.objects where object_id = object_id(N'dbo.fnGetNumberString'))
drop function fnGetNumberString
go
/*
Tests:
declare @tests table ( testValue bigint )
insert into @tests select -43213 union select -5 union select 0 union select 2 union select 15 union select 33 union select 100 union select 456 union select 1024 union select 10343 union select 12345678901234 union select -3434343434343
select testValue, dbo.fnGetNumberString(testValue) as textValue
from @tests
*/
create function dbo.fnGetNumberString
(
@value bigint
)
returns nvarchar(1024)
as
begin
if @value = 0 return 'zero' -- lets me avoid special-casing this later
declare @isNegative bit
set @isNegative = 0
if @value < 0
select @isNegative = 1, @value = @value * -1
declare @groupNames table ( groupOrder int, groupName nvarchar(15) )
insert into @groupNames select 1, '' union select 2, 'thousand' union select 3, 'million' union select 4, 'billion' union select 5, 'trillion' union select 6, 'quadrillion' union select 7, 'quintillion' union select 8, 'sextillion'
declare @digitNames table ( digit tinyint, digitName nvarchar(10) )
insert into @digitNames select 0, '' union select 1, 'one' union select 2, 'two' union select 3, 'three' union select 4, 'four' union select 5, 'five' union select 6, 'six' union select 7, 'seven' union select 8, 'eight' union select 9, 'nine' union select 10, 'ten' union select 11, 'eleven' union select 12, 'twelve' union select 13, 'thirteen' union select 14, 'fourteen' union select 15, 'fifteen' union select 16, 'sixteen' union select 17, 'seventeen' union select 18, 'eighteen' union select 19, 'nineteen'
declare @tensGroups table ( digit tinyint, groupName nvarchar(10) )
insert into @tensGroups select 2, 'twenty' union select 3, 'thirty' union select 4, 'forty' union select 5, 'fifty' union select 6, 'sixty' union select 7, 'seventy' union select 8, 'eighty' union select 9, 'ninety'
declare @groups table ( groupOrder int identity, groupValue int )
declare @convertedValue varchar(50)
while @value > 0
begin
insert into @groups (groupValue) select @value % 1000
set @value = @value / 1000
end
declare @returnValue nvarchar(1024)
set @returnValue = ''
if @isNegative = 1 set @returnValue = 'negative'
select @returnValue = @returnValue +
case when len(h.digitName) > 0 then ' ' + h.digitName + ' hundred' else '' end +
case when len(isnull(t.groupName, '')) > 0 then ' ' + t.groupName + case when len(isnull(o.digitName, '')) > 0 then '-' else '' end + isnull(o.digitName, '') else case when len(isnull(o.digitName, '')) > 0 then ' ' + o.digitName else '' end end +
case when len(n.groupName) > 0 then ' ' + n.groupName else '' end
from @groups g
join @groupNames n on n.groupOrder = g.groupOrder
join @digitNames h on h.digit = (g.groupValue / 100)
left join @tensGroups t on t.digit = ((g.groupValue % 100) / 10)
left join @digitNames o on o.digit = case when (g.groupValue % 100) < 20 then g.groupValue % 100 else g.groupValue % 10 end
order by g.groupOrder desc
return @returnValue
end
go
Voici une solution Scala. Je ne suis pas heureux d'essayer de le faire paraître court -- j'ai sacrifié un peu de lisibilité : (
object NumSpeller { val digits = Array("","one","two","three","four","five","six","seven","eight","nine") val teens = Array("ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen") val tens = Array("", "ten", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety") val thousands = Array("", "thousand", "million", "billion", "trillion", "quadrillion", "quintillion") def spellGroup(num:Int) = { val (v3, v2, v1) = ((num / 100) % 10, (num / 10) % 10, num % 10) val hs = v3 match { case 0 => ""; case d => digits(d) + " hundred " } val ts = v2 match { case 0 => digits(v1) case 1 => teens(v1) case _ => v3 match { case 0 => tens(v2); case _ => tens(v2) + "-" + digits(v1) } } hs + ts } def numberGroups(num:Long) = { def _numberGroups(num:Long, factor:Int):List[(Double,Int)] = factor match { case 0 => List((num % 1000,0)) case _ => ((num / Math.pow(1000, factor)) % 1000, factor) :: _numberGroups(num, factor - 1) } val ints = _numberGroups(num, 6) map (x => (x._1.asInstanceOf[Int],x._2)) ints dropWhile (x => x._1 == 0.0) } def spell(num:Long) = num match { case 0 => "zero"; case _ => (numberGroups(num) map { x => spellGroup(x._1) + " " + thousands(x._2) + " " }).mkString.trim } }
Usage:
NumSpeller.spell(458582)
Perl 5.10
my %expo=(0,'',
qw'1 thousand 2 million 3 billion 4 trillion 5 quadrillion 6 quintillion
7 sextillion 8 septillion 9 octillion 10 nonillion 11 decillion 12 undecillion
13 duodecillion 14 tredecillion 15 quattuordecillion 16 quindecillion
17 sexdecillion 18 septendecillion 19 octodecillion 20 novemdecillion
21 vigintillion'
);
my %digit=(0,'',
qw'1 one 2 two 3 three 4 four 5 five 6 six 7 seven 8 eight 9 nine 10 ten
11 eleven 12 twelve 13 thirteen 14 fourteen 15 fifteen 16 sixteen 17 seventeen
18 eighteen 19 nineteen 2* twenty 3* thirty 4* forty 5* fifty 6* sixty
7* seventy 8* eighty 9* ninety'
);
sub spell_number(_){
local($_)=@_;
($_,@_)=split/(?=(?:.{3})*+$)/;
$_=0 x(3-length).$_;
unshift@_,$_;
my @o;
my $c=@_;
for(@_){
my $o='';
/(.)(.)(.)/;
$o.=?$digit{}.' hundred':'';
$o.===1?
' '.$digit{.}
:
(?' '.$digit{"*"}:'').
(&&?' ':'').
$digit{}
;
$o.=--$c?($o?' '.$expo{$c}.', ':''):'';
push@o,$o;
}
my $o;
$o.=$_ for@o;
$o=~/^\s*+(.*?)(, )?$/;
$o?:'zero';
}
Notes:
- cela fonctionne presque sur Perls plus tôt, c'est ce premier
split()
qui semble être le problème principal. Comme il se trouve maintenant les cordes prennent le gros des caractères. - j'aurais pu le raccourcir, en enlevant les
my
's, et lelocal
, ainsi que mettre tout sur une ligne. - j'ai utilisé numéro:: orthographe comme point de départ.
- Fonctionne sous
strict
etwarnings
.
Mmm, vous auriez pu mettre la barre un peu haut, les deux sur la limite (18,446,744,073,709,552,000, Je ne sais même pas comment écrire cela!) et sur le but (les autres golfs de code ont abouti au code court, celui-ci sera long au moins pour les données (mots)).
quoi qu'il en soit, pour mémoire, je donne une solution bien connue (pas la mienne!) pour le français, en PHP: Écriture des nombres en français . :- )
noter l'ambiguïté (volontaire ou non) de votre libellé: " soumissions dans n'importe quelle langue welcome
J'ai d'abord pris comme "langue naturelle", avant de comprendre que vous signifiait probablement "langage de programmation...
L'algorithme est probablement plus simple en anglais (et avec moins de variantes régionales...).
dans le d langage de programmation
string Number(ulong i)
{
static string[] names = [
""[],
" thousand",
" million",
" billion",
" trillion",
" quadrillion",
];
string ret = null;
foreach(mult; names)
{
if(i%1000 != 0)
{
if(ret != null) ret = ret ~ ", "
ret = Cent(i%1000) ~ mult ~ ret;
}
i /= 1000;
}
return ret;
}
string Cent(int i)
{
static string[] v =
[""[], "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine"];
static string[] tens =
["!"[], "!", "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"];
string p1, p2, p3 = "";
if(i >= 100)
{
p1 = v[i/100] ~ " hundred";
p3 = (i % 100 != 0) ? " and " : ""; //optional
}
else
p1 = "";
i %= 100;
switch(i)
{
case 0, 1, 2, 3, 4, 5, 6, 7, 8, 9:
p2 = v[i];
break;
case 10: p2 = "ten"; break;
case 11: p2 = "eleven"; break;
case 12: p2 = "twelve"; break;
case 13: p2 = "thirteen"; break;
case 14: p2 = "fourteen"; break;
case 15: p2 = "fifteen"; break;
case 16: p2 = "sixteen"; break;
case 17: p2 = "seventeen"; break;
case 18: p2 = "eighteen"; break;
case 19: p2 = "nineteen"; break;
default:
p2 = tens[i/10] ~ "-" ~ v[i%10];
break;
}
return p1 ~ p3 ~ p2;
}
import std.stdio;
void main()
{
writef("%s\n", Number(8_000_400_213));
}
est-ce que quelqu'un prévoit d'ajouter les guillemets et " et " appropriés bientôt? Ou hyphenating vingt-et-un par le biais de quatre-vingt-dix-neuf? Pas beaucoup de point sinon, à mon humble avis :)
'Neuf Cent Quatre-Vingt-Dix Neuf Mille Neuf Cent Quatre-Vingt-Dix Neuf"
vs
'Neuf cent quatre-vingt-dix-neuf mille neuf cent quatre-vingt-dix-neuf"
(Et non, le mien ne fonctionne pas. Encore.)
#!/usr/bin/env perl
my %symbols = (
1 => "One", 2 => "Two", 3 => "Three", 4 => "Four", 5 => "Five",
6 => "Six", 7 => "Seven", 8 => "Eight", 9 => "Nine", 10 => "Ten",
11 => "Eleven", 12 => "Twelve", 13 => "Thirteen", 14 => "Fourteen",
15 => "Fifteen", 16 => "Sixteen", 17 => "Seventeen", 18 => "Eighteen",
19 => "Nineteen", 20 => "Twenty", 30 => "Thirty", 40 => "Forty",
50 => "Fifty", 60 => "Sixty", 70 => "Seventy", 80 => "Eighty",
90 => "Ninety", 100 => "Hundred");
my %three_symbols = (1 => "Thousand", 2 => "Million", 3 => "Billion" );
sub babo {
my ($input) = @_;
my @threes = split(undef, $input);
my $counter = ($#threes + 1);
my $remainder = $counter % 3;
my @result;
while ($counter > 0){
my $digits = "";
my $three;
my $full_match = 0;
if ($remainder > 0){
while ($remainder > 0) {
$digits .= shift(@threes);
$remainder--;
$counter--;
}
}
else {
$digits = join('',@threes[0,1,2]);
splice(@threes, 0, 3);
$counter -= 3;
}
if (exists($symbols{$digits})){
$three = $symbols{$digits};
$full_match = 1;
}
elsif (length($digits) == 3) {
$three = $symbols{substr($digits,0,1)};
$three .= " Hundred";
$digits = substr($digits,1,2);
if (exists($symbols{$digits})){
$three .= " " . $symbols{$digits};
$full_match = 1;
}
}
if ($full_match == 0){
$three .= " " . $symbols{substr($digits,0,1)."0"};
$three .= " " . $symbols{substr($digits,1,1)};
}
push(@result, $three);
if ($counter > 0){
push(@result, "Thousand");
}
}
my $three_counter = 0;
my @r = map {$_ eq "Thousand" ? $three_symbols{++$three_counter}:$_ }
reverse @result;
return join(" ", reverse @r);
}
print babo(1) . "\n";
print babo(12) . "\n";
print babo(120) . "\n";
print babo(1234) . "\n";
print babo(12345) . "\n";
print babo(123456) . "\n";
print babo(1234567) . "\n";
print babo(1234567890) . "\n";
Je ne peux pas trouver le fichier maintenant, mais c'était une introduction au problème de programmation (tard dans le terme) où je suis allé à l'école. Nous devions être en mesure de transformer un flotteur en un numéro écrit valide pour une vérification.
une fois le travail terminé, le professeur a montré du code C++ qui a résolu le problème en utilisant seulement les concepts que nous avions déjà couverts. Il ne contenait que 43 lignes et était bien documenté.
/ Perl CPAN travailler ensemble:
#!/usr/bin/perl
use strict;
use warnings;
use Lingua::EN::Numbers qw(num2en);
print num2en($_), "\n" for 2, 1024, 1024*1024;
C:\Temp> n.pl two one thousand and twenty-four one million, forty-eight thousand, five hundred and seventy-six
voici un en PHP, de convertir des nombres en mots :
convert_number(2850)
retourne
deux mille huit cent cinquante
et si vous voulez un encore plus impressionnant qui traite des virgules et des numéros jusqu'à vigintillon vérifier zac hesters travailler à fonctions D'affichage de langue :
function convert_number($number)
{
if (($number < 0) || ($number > 999999999))
{
throw new Exception("Number is out of range");
}
$Gn = floor($number / 1000000); /* Millions (giga) */
$number -= $Gn * 1000000;
$kn = floor($number / 1000); /* Thousands (kilo) */
$number -= $kn * 1000;
$Hn = floor($number / 100); /* Hundreds (hecto) */
$number -= $Hn * 100;
$Dn = floor($number / 10); /* Tens (deca) */
$n = $number % 10; /* Ones */
$res = "";
if ($Gn)
{
$res .= convert_number($Gn) . " Million";
}
if ($kn)
{
$res .= (empty($res) ? "" : " ") .
convert_number($kn) . " Thousand";
}
if ($Hn)
{
$res .= (empty($res) ? "" : " ") .
convert_number($Hn) . " Hundred";
}
$ones = array("", "One", "Two", "Three", "Four", "Five", "Six",
"Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen",
"Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eightteen",
"Nineteen");
$tens = array("", "", "Twenty", "Thirty", "Fourty", "Fifty", "Sixty",
"Seventy", "Eigthy", "Ninety");
if ($Dn || $n)
{
if (!empty($res))
{
$res .= " and ";
}
if ($Dn < 2)
{
$res .= $ones[$Dn * 10 + $n];
}
else
{
$res .= $tens[$Dn];
if ($n)
{
$res .= "-" . $ones[$n];
}
}
}
if (empty($res))
{
$res = "zero";
}
return $res;
}
il y a quelques années, j'ai créé ceci en C# pour des applications multilingues.
c'est la classe de base:
public abstract class ValueSource
{
public abstract object Value { get; }
}
celui-ci est pour wordify..
public abstract class NumberTextValueSource:ValueSource
{
public abstract decimal Number { get; }
public abstract string Format { get; }
public abstract string Negative { get; }
public abstract bool UseValueIfZero { get; }
public abstract string N0 { get; }
public abstract string N1 { get; }
public abstract string N2 { get; }
public abstract string N3 { get; }
public abstract string N4 { get; }
public abstract string N5 { get; }
public abstract string N6 { get; }
public abstract string N7 { get; }
public abstract string N8 { get; }
public abstract string N9 { get; }
public abstract string N10 { get; }
public abstract string N11 { get; }
public abstract string N12 { get; }
public abstract string N13 { get; }
public abstract string N14 { get; }
public abstract string N15 { get; }
public abstract string N16 { get; }
public abstract string N17 { get; }
public abstract string N18 { get; }
public abstract string N19 { get; }
public abstract string N20 { get; }
public abstract string N30 { get; }
public abstract string N40 { get; }
public abstract string N50 { get; }
public abstract string N60 { get; }
public abstract string N70 { get; }
public abstract string N80 { get; }
public abstract string N90 { get; }
public abstract string N100 { get; }
public abstract string NHundred { get; }
public abstract string N1000 { get; }
public abstract string NThousand { get; }
public abstract string NMillion { get; }
public abstract string NBillion { get; }
public abstract string NTrillion { get; }
public abstract string NQuadrillion { get; }
string getOne(Type t, string v)
{
if (v[0] == '0' && !UseValueIfZero)
return "";
return (string)t.GetProperty("N" + v[0].ToString()).GetValue(this, null);
}
string getTwo(Type t, string v)
{
if (v[0] == '0')
if (v[1] != '0')
return getOne(t, v.Substring(1));
else
return "";
if (v[1] == '0' || v[0] == '1')
return (string)t.GetProperty("N" + v).GetValue(this, null);
return (string)t.GetProperty("N" + v[0].ToString() + "0").GetValue(this, null) +
getOne(t, v.Substring(1));
}
string getThree(Type t, string v)
{
if(v[0] == '0')
return getTwo(t,v.Substring(1));
if (v[0] == '1')
return
N100 +
getTwo(t, v.Substring(1));
return
getOne(t, v[0].ToString()) +
NHundred +
getTwo(t, v.Substring(1));
}
string getFour(Type t, string v)
{
if (v[0] == '0')
return getThree(t, v.Substring(1));
if (v[0] == '1')
return
N1000 +
getThree(t, v.Substring(1));
return
getOne(t, v[0].ToString()) +
NThousand +
getThree(t, v.Substring(1));
}
string getFive(Type t, string v)
{
if (v[0] == '0')
return getFour(t, v.Substring(1));
return
getTwo(t, v.Substring(0, 2)) +
NThousand +
getThree(t, v.Substring(2));
}
string getSix(Type t, string v)
{
if (v[0] == '0')
return getFive(t, v.Substring(1));
return
getThree(t, v.Substring(0, 3)) +
NThousand +
getThree(t, v.Substring(3));
}
string getSeven(Type t, string v)
{
if (v[0] == '0')
return getSix(t, v.Substring(1));
return
getOne(t, v[0].ToString()) +
NMillion +
getSix(t, v.Substring(3));
}
string getEight(Type t, string v)
{
if (v[0] == '0')
return getSeven(t, v.Substring(1));
return
getTwo(t, v.Substring(0, 2)) +
NMillion +
getSix(t, v.Substring(2));
}
string getNine(Type t, string v)
{
if (v[0] == '0')
return getEight(t, v.Substring(1));
return
getThree(t, v.Substring(0, 3)) +
NMillion +
getSix(t, v.Substring(3));
}
string getTen(Type t, string v)
{
if (v[0] == '0')
return getNine(t, v.Substring(1));
return
getOne(t, v.Substring(0, 1)) +
NBillion +
getNine(t, v.Substring(1));
}
string getEleven(Type t, string v)
{
if (v[0] == '0')
return getTen(t, v.Substring(1));
return
getTwo(t, v.Substring(0, 2)) +
NBillion +
getNine(t, v.Substring(2));
}
string getTwelve(Type t, string v)
{
if (v[0] == '0')
return getEleven(t, v.Substring(1));
return
getThree(t, v.Substring(0, 3)) +
NBillion +
getNine(t, v.Substring(3));
}
string getThirteen(Type t, string v)
{
if (v[0] == '0')
return getTwelve(t, v.Substring(1));
return
getOne(t, v.Substring(0, 1)) +
NTrillion +
getTwelve(t, v.Substring(1));
}
string getForteen(Type t, string v)
{
if (v[0] == '0')
return getThirteen(t, v.Substring(1));
return
getTwo(t, v.Substring(0, 2)) +
NTrillion +
getTwelve(t, v.Substring(2));
}
string getFifteen(Type t, string v)
{
if (v[0] == '0')
return getForteen(t, v.Substring(1));
return
getThree(t, v.Substring(0, 3)) +
NTrillion +
getTwelve(t, v.Substring(3));
}
string getSixteen(Type t, string v)
{
if (v[0] == '0')
return getFifteen(t, v.Substring(1));
return
getOne(t, v.Substring(0, 1)) +
NQuadrillion +
getFifteen(t, v.Substring(1));
}
string getSeventeen(Type t, string v)
{
if (v[0] == '0')
return getSixteen(t, v.Substring(1));
return
getTwo(t, v.Substring(0, 2)) +
NQuadrillion +
getFifteen(t, v.Substring(2));
}
string getEighteen(Type t, string v)
{
if (v[0] == '0')
return getSeventeen(t, v.Substring(1));
return
getThree(t, v.Substring(0, 3)) +
NQuadrillion +
getFifteen(t, v.Substring(3));
}
string convert(Type t, string hp)
{
switch (hp.Length)
{
case 1:
return getOne(t, hp);
case 2:
return getTwo(t, hp);
case 3:
return getThree(t, hp);
case 4:
return getFour(t, hp);
case 5:
return getFive(t, hp);
case 6:
return getSix(t, hp);
case 7:
return getSeven(t, hp);
case 8:
return getEight(t, hp);
case 9:
return getNine(t, hp);
case 10:
return getTen(t, hp);
case 11:
return getEleven(t, hp);
case 12:
return getTwelve(t, hp);
case 13:
return getThirteen(t, hp);
case 14:
return getForteen(t, hp);
case 15:
return getFifteen(t, hp);
case 16:
return getSixteen(t, hp);
case 17:
return getSeventeen(t, hp);
case 18:
return getEighteen(t, hp);
}
return "";
}
public override object Value
{
get
{
decimal d = Number;
decimal highPoint, lowPoint;
bool isNeg = d < 0;
d = Math.Abs(d);
highPoint = Math.Floor(d);
lowPoint = d - highPoint;
Type t = this.GetType();
string strHigh = convert(t, highPoint.ToString()),
strLow =
lowPoint > 0 ?
convert(t, lowPoint.ToString().Substring(2)) :
UseValueIfZero ? N0 : "";
if (isNeg) strHigh = Negative + " " + strHigh;
return string.Format(Format, strHigh, strLow);
}
}
}
et celui-ci est pour Turkish Lera (TRY):
public class TRYNumberTextValueSource:NumberTextValueSource
{
decimal num;
public TRYNumberTextValueSource(decimal value)
{
num = Math.Round(value, 2);
}
public override decimal Number
{
get { return num; }
}
public override string Format
{
get
{
if (num == 0)
return N0 + " YTL";
if (num > -1 && num < 1)
return "{0}{1} Kurus";
return "{0} YTL {1} Kurus";
}
}
public override string Negative
{
get { return "-"; }
}
public override bool UseValueIfZero
{
get { return false; }
}
public override string N0
{
get { return "sifir"; }
}
public override string N1
{
get { return "bir"; }
}
public override string N2
{
get { return "iki"; }
}
public override string N3
{
get { return "üç"; }
}
public override string N4
{
get { return "dört"; }
}
public override string N5
{
get { return "bes"; }
}
public override string N6
{
get { return "alti"; }
}
public override string N7
{
get { return "yedi"; }
}
public override string N8
{
get { return "sekiz"; }
}
public override string N9
{
get { return "dokuz"; }
}
public override string N10
{
get { return "on"; }
}
public override string N11
{
get { return "onbir"; }
}
public override string N12
{
get { return "oniki"; }
}
public override string N13
{
get { return "onüç"; }
}
public override string N14
{
get { return "ondört"; }
}
public override string N15
{
get { return "onbes"; }
}
public override string N16
{
get { return "onalti"; }
}
public override string N17
{
get { return "onyedi"; }
}
public override string N18
{
get { return "onsekiz"; }
}
public override string N19
{
get { return "ondokuz"; }
}
public override string N20
{
get { return "yirmi"; }
}
public override string N30
{
get { return "otuz"; }
}
public override string N40
{
get { return "kirk"; }
}
public override string N50
{
get { return "elli"; }
}
public override string N60
{
get { return "altmis"; }
}
public override string N70
{
get { return "yetmis"; }
}
public override string N80
{
get { return "seksen"; }
}
public override string N90
{
get { return "doksan"; }
}
public override string N100
{
get { return "yüz"; }
}
public override string NHundred
{
get { return "yüz"; }
}
public override string N1000
{
get { return "bin"; }
}
public override string NThousand
{
get { return "bin"; }
}
public override string NMillion
{
get { return "milyon"; }
}
public override string NBillion
{
get { return "milyar"; }
}
public override string NTrillion
{
get { return "trilyon"; }
}
public override string NQuadrillion
{
get { return "trilyar"; }
}
}
et il est utilisé de cette façon:
MessageBox.show((string)(new TRYNumberTextValueSource(12345)).Value);