Épeler les chiffres en français

23

Il était difficile de convertir un nombre en chiffres en anglais , mais c'était trop simple. Étant donné un nombre compris entre 0 et 100, votre tâche consiste à sortir le chiffre correspondant en français. Le système numérique français a une logique plus complexe derrière lui que le système anglais:

Chiffre numérique
---------------
 0 zéro (notez l'accent)
 1 un
 2 deux
 3 trois
 4 quatre
 5 cinq
 6 six
 7 Sept
 8 huit
 9 neuf
10 dix
11 onze
12 douze
13 treize
14 quatorze
15 quinze
16 saisir
17 dix-sept (littéralement dix sept)
18 dix-huit
19 dix-neuf
20 vingt
21 vingt et un (pas de tirets)
22 vingt-deux
...
30 trente
...
40 quarante
...
50 cinquante
...
60 soixante
...
70 soixante-dix (littéralement soixante dix)
71 soixante et onze
...
80 quatre-vingts (notez les s; littéralement quatre vingt)
81 quatre-vingt-un (notez les tirets)
...
90 quatre-vingt-dix
91 quatre-vingt-onze
...
99 quatre-vingt-dix-neuf (4 * 20 + 10 + 9)
100 cent

Pour une liste complète, suivez http://quizlet.com/996950/ ( http://www.webcitation.org/6RNppaJx0 ).

Autres règles / explications

  • Il y aura toujours un trait d'union entre les mots SAUF lorsque le nombre se termine par 1.
  • Lorsque le nombre se termine par 1, le mot et (signifiant et ) est ajouté avant l' un ou l' onze . (31 = trente et un)
  • Cependant, 81 et 91 sont formatés de la même manière que les autres nombres. (81 = quatre-vingt-un)
  • À 60, le système passe de la base 10 à la base 20.
  • Il existe quelques différences mineures à ce sujet sur le Web; reportez-vous à la liste ci-dessus pour les questions.
  • Les failles interdites par défaut ne sont pas autorisées.
  • L'utilisation d'une source externe telle qu'un site Web, ainsi que toutes bibliothèques, API, fonctions ou similaires qui convertissent des nombres en chiffres ou traduisent en français ne sont pas autorisées.
  • Il s'agit de , donc la réponse avec le moins d'octets l'emporte.
  • Si disponible, veuillez créer un lien vers un compilateur en ligne pour permettre un test facile de votre code.

Contribution

  • L'entrée doit provenir de votre langue. (STDIN, ligne de commande, etc.)
  • L'entrée sera une seule chaîne, composée d'un nombre entier compris entre 0 et 100 inclus (zéros non significatifs en option).
  • Vous pouvez supposer que l'entrée sera toujours bien formée.

Sortie

  • Le résultat sera transmis à la méthode la plus pratique pour votre langue. (STDOUT, boîte de dialogue, etc.)
  • La casse n'a pas d'importance dans la sortie.

Exemples

Testez votre code par rapport à ceux-ci:

Entrée sortie
-------------
0 zéro
18 dix-huit
51 cinquante et un
80 quatre-vingts
91 quatre-vingt-onze
99 quatre-vingt-dix-neuf
NinjaBearMonkey
la source
3
A noter que les Belges francophones utilisent "septante", "octante" et "nonante" au lieu de soixante-dix, quatre-vingts, quatre-vingt-dix. Il devrait être utilisé dans l'ancienne colonie belge.
Emmanuel
8
+1 pour le génie de le faire en français. Comme l'a dit un de mes collègues allemands: "Les Allemands disent les chiffres à l'envers. Mais pour comprendre le français, vous avez besoin d'une calculatrice."
Level River St
1
Il semble que zéro soit le seul nombre accentué dans la plage 0-100. Ce n'est pas un caractère ASCII standard. Je suppose que tout format (page de codes 437, UTF-8, etc.) pouvant produire ce caractère est acceptable.
Level River St
1
@Martin Les règles indiquent "Vous pouvez supposer que l'entrée sera toujours bien formée", donc une entrée> 100 peut entraîner n'importe quel comportement.
NinjaBearMonkey
3
Il n'y a absolument aucune logique derrière le système français. Je suis sûr qu'il y a une erreur dans 99% des chèques français, c'est encore plus compliqué après 100. La conjugaison est aussi un cauchemar. Croyez-moi, je suis français.
Michael M.

Réponses:

7

JavaScript (ES6) 318 321

Modifier le correctif de bogue (gérer les premiers 0) et jouer au golf plus

Crédit pour l'astuce de l'affaire de chameau @ Core1024

Avec entrée / sortie via popup

alert((n=prompt(),w='ZéroUnDeuxTroisQuatreCinqSixSeptHuitNeufDixOnzeDouzeTreizeQuatorzeQuinzeSeizeDix-septDix-huitDix-neufVingtTrenteQuaranteCinquanteSoixante'.match(/[A-Z][^A-Z]+/g),
u=n%10,s=u-1|n>80?d='-':' et ',n>99?'Cent':n<21?w[n|0]:n<70?w[18+n/10|0]+(u?s+w[u]:''):(n<80?w[24]:w[4]+d+w[20])+(n-80?s+w[n%20]:'s')))

Comme fonction testable

F=n=>(
  w='ZéroUnDeuxTroisQuatreCinqSixSeptHuitNeufDixOnzeDouzeTreizeQuatorzeQuinzeSeizeDix-septDix-huitDix-neufVingtTrenteQuaranteCinquanteSoixante'
  .match(/[A-Z][^A-Z]+/g),
  u=n%10,s=u-1|n>80?d='-':' et ',
  n>99?'Cent':
  n<21?w[n|0]:
  n<70?w[18+n/10|0]+(u?s+w[u]:''):
  (n<80?w[24]:w[4]+d+w[20])+(n-80?s+w[n%20]:'s')
)

Pour tester dans la console FireFox ou FireBug

for (i = 0; i < 100; console.log(r),i+= 10) 
  for (j=0, r=''; j < 10; j++)
    r+=(i+j)+':'+F(i+j+'')+", "; // specific: input is a string
F('100')

Sortie de test

0: Zéro, 1: Un, 2: Deux, 3: Trois, 4: Quatre, 5: Cinq, 6: Six, 7: Sept, 8: Huit, 9: Neuf,
10: Dix, 11: Onze, 12: Douze, 13: Treize, 14: Quatorze, 15: Quinze, 16: Seize, 17: Dix-sept, 18: Dix-huit, 19: Dix-neuf,
20: Vingt, 21: Vingt et Un, 22: Vingt-Deux, 23: Vingt-Trois, 24: Vingt-Quatre, 25: Vingt-Cinq, 26: Vingt-Six, 27: Vingt-Sept, 28: Vingt- Huit, 29: Vingt-Neuf,
30: Trente, 31: Trente et Un, 32: Trente-Deux, 33: Trente-Trois, 34: Trente-Quatre, 35: Trente-Cinq, 36: Trente-Six, 37: Trente-Sept, 38: Trente- Huit, 39 ans: Trente-Neuf,
40: Quarante, 41: Quarante et Un, 42: Quarante-Deux, 43: Quarante-Trois, 44: Quarante-Quatre, 45: Quarante-Cinq, 46: Quarante-Six, 47: Quarante-Sept, 48: Quarante- Huit, 49: Quarante-Neuf,
50: Cinquante, 51: Cinquante et Un, 52: Cinquante-Deux, 53: Cinquante-Trois, 54: Cinquante-Quatre, 55: Cinquante-Cinq, 56: Cinquante-Six, 57: Cinquante-Sept, 58: Cinquante- Huit, 59: Cinquante-Neuf,
60: Soixante, 61: Soixante et Un, 62: Soixante-Deux, 63: Soixante-Trois, 64: Soixante-Quatre, 65: Soixante-Cinq, 66: Soixante-Six, 67: Soixante-Sept, 68: Soixante- Huit, 69: Soixante-Neuf,
70: Soixante-Dix, 71: Soixante et Onze, 72: Soixante-Douze, 73: Soixante-Treize, 74: Soixante-Quatorze, 75: Soixante-Quinze, 76: Soixante-Seize, 77: Soixante-Dix-sept, 78: Soixante-Dix-huit, 79: Soixante-Dix-neuf,
80: Quatre-Vingts, 81: Quatre-Vingt-Un, 82: Quatre-Vingt-Deux, 83: Quatre-Vingt-Trois, 84: Quatre-Vingt-Quatre, 85: Quatre-Vingt-Cinq, 86: Quatre- Vingt-Six, 87: Quatre-Vingt-Sept, 88: Quatre-Vingt-Huit, 89: Quatre-Vingt-Neuf,
90: Quatre-Vingt-Dix, 91: Quatre-Vingt-Onze, 92: Quatre-Vingt-Douze, 93: Quatre-Vingt-Treize, 94: Quatre-Vingt-Quatorze, 95: Quatre-Vingt-Quinze, 96: Quatre-Vingt-Seize, 97: Quatre-Vingt-Dix-sept, 98: Quatre-Vingt-Dix-huit, 99: Quatre-Vingt-Dix-neuf, 
"Cent"
edc65
la source
2
Astuce cool avec l'étui à chameaux!
tomsmeding
@tomsmeding vraiment cool donc évidemment pas imaginé par moi (crédit ajouté dans le post)
edc65
@ edc65 Cela vous dérange si j'essaie d'améliorer ma réponse Ruby avec ça? Je n'ai même pas vu que la sortie insensible à la casse est autorisée lorsque j'ai écrit la mienne. ^^
Martin Ender
@ MartinBüttner bien sûr, vous pouvez
edc65
6

Haskell, 390 octets

b=(words"zéro un deux trois quatre cinq six sept huit neuf dix onze douze treize quatorze quinze seize vingt trente quarante cinquante soixante"!!)
a!b=a++"-"++b
f 0=b 0
f 71=f 60++" et onze"
f 80=f 4!b 17++"s"
f 100="cent"
f x|x<17=b x|x<20=b 10!b(x-10)|x>80=b 4!b 17!f(x-80)|m==1=f(x-1)++" et un"|x>60=f 60!f(x-60)|m==0=b(15+div x 10)|1<2=f(x-m)!f m where m=mod x 10
main=interact$f.read

Non golfé

base :: Int -> String
--              0    1  2    3     4      5    6   7    8    9    10  11   12     13     14       15     16    17    18     19       20        21      
base i = words "zéro un deux trois quatre cinq six sept huit neuf dix onze douze  treize quatorze quinze seize vingt trente quarante cinquante soixante" !! i

hyphen :: String -> String -> String
a `hyphen` b = a ++ "-" ++ b

say :: Int -> String
say 0 = base 0
say 71 = say 60 ++ " et onze"
say 80 = say 4 `hyphen` base 17 ++ "s"
say 100 = "cent"
say x
  | x < 17 = base x
  | x < 20 = base 10 `hyphen` base (x - 10)
  | x > 80 = base 4 `hyphen` base 17 `hyphen` say (x - 80)
  | m == 1 = say (x - 1) ++ " et un"
  | x > 60 = say 60 `hyphen` say (x - 60)
  | m == 0 = base (div x 10 + 15)
  | otherwise = say (x - m) `hyphen` say m
  where m = mod x 10

main = putStr.say.read=<<getLine

Les langages de programmation fonctionnels conviennent parfaitement à ce travail.

Rayon
la source
Ayez un vote positif, vous étiez plus rapide que moi. Vous voudrez peut-être remplacer votre main par main=interact$f.readet enregistrer quelques caractères.
gxtaillon
@gxtaillon Oui, j'ai oublié interact. Mis à jour.
Ray
5

Rubis, 333 octets

l=['']+%w{un deux trois quatre cinq six sept huit neuf dix onze douze treize quatorze quinze seize}
d=%w{vingt trente quarante cinquante soixante _ quatre-vingt}+['']*2
n=gets.to_i
v=n%20
t=n%10
puts n<1?'zéro':n>99?'cent':d[(n<70?n:n-v)/10-2]+(n<21||t<1&&n<61?'':v<1??s:t==1&&n<80?' et ':?-)+(n>60||n<20?v<17?l[v]:'dix-'+l[t]:l[t])

Ce ne sont généralement que deux tables de recherche et un tas d'opérateurs ternaires qui codent toutes les règles étranges et vous indiquent quelle table de recherche utiliser quand. Faites-moi savoir si vous voulez en savoir plus. ;)

Martin Ender
la source
1
Déteste être nitpicky, mais 80devrait produire quatre vingts, avec un s à la fin.
NinjaBearMonkey
@hsl corrigé et raccourci un peu.
Martin Ender
5

Python - 344 (348) (380) (445) (537) octets

Merci à grc, Ray et isaacg pour leur aide dans le processus de golf.

Le code se compose de la définition initiale du dictionnaire et d'une compréhension de liste qui remplit les blancs avec la jonction des éléments du dictionnaire.

Vous pouvez vérifier le code en ligne sur repl.it

r=range
def f(a):b=a/60*10+10;d[a]=d[a-a%b]+(' et ','-')[a%10!=1or a>80]+d[a%b]
d=dict(zip(r(17)+r(20,70,10)+[80,100],'zéro un deux trois quatre cinq six sept huit neuf dix onze douze treize quatorze quinze seize vingt trente quarante cinquante soixante quatre-vingt cent'.split()))
[f(v)for v in r(100)if(v in d)<1]
d[80]+='s'
print d[input()]

Mes dernières tentatives pour jouer à ce code ont été de renoncer au processus de génération et avec cette réduction d'affiner la fonction pour générer simplement le numéro demandé sur place. Cependant, comme les nombres des années 60 et 80 ont besoin d'éléments non calculés, la difficulté a été de créer une telle fonction tout en diminuant le code.

Doktoro Reichard
la source
3
Vous pouvez utiliser r=range, cette astuce pour les lignes 2 et 3, et un seul espace pour l' indentation. Et vous pouvez économiser 65 octets avecd=dict(zip(r(17)+r(20,70,10)+[80,100],'zéro un deux ... quatre-vingt cent'.split()))
grc
L' r=rangeastuce que je connaissais, mais j'ai oublié de l'ajouter lorsque j'ai écrit la première révision. Tout le reste était relativement nouveau pour moi, alors merci. Une note cependant, le code ne fonctionne pas sur Python 3.x sauf si l' printinstruction est transformée en fonction et les rfonctions dans le dict sont transformées en listes.
Doktoro Reichard
En python 2, vous n'avez pas besoin int(input()), input()c'est suffisant.
Ray
1
Quelques conseils: Je pense que si vous mettez b=a/60*10+10en f(a)vous pouvez ensuite utiliser a-a%bet a%bpour vos clés de dictionnaire. De plus, vous n'avez pas besoin d'espace 1 oret la 4ème ligne peut être raccourcie [f(v)for v in r(100)if v not in d]. Je n'ai pourtant rien essayé de tout cela.
grc
1
if v not in d-> if(v in d)<1enregistre un personnage. Si vous séparez les deux parties de votre fonction par un point-virgule, vous pouvez tout mettre sur une seule ligne.
isaacg
4

Python - 392 octets

Il a une liste avec des numéros de base qu'il utilise pour générer les autres numéros. La plupart de la logique de génération se trouve dans la compréhension de liste sur la ligne 2, en utilisant l'indexation de liste pour les conditions. Une fois la liste générée, elle recherche le numéro saisi et l'imprime.

Edit: raccourci de 426 octets en utilisant la pointe de grc.

a='_un_deux_trois_quatre_cinq_six_sept_huit_neuf_dix_onze_douze_treize_quatorze_quinze_seize_dix-sept_dix-huit_dix-neut'.split('_')
a+=[[['vingt','trente'],['quarante','cinquante'],['soixante']*2,[a[4]+'-vingt']*2][b][c>9]+['','-',' et '][(c%[10,20][b>1]>0)+(c%10==1)*(b<3)]+a[c%[10,20][b>1]]for b in[0,1,2,3]for c in range(20)]
a[0]='zéro'
a[80]+='s'
a+=['cent']
print(a[int(input())])
faubi
la source
1
Vous pouvez enregistrer 23 octets aveca='_un_deux_trois ... quinze_seize'.split('_')
grc
5
Il y a une faute de frappe: ciquante , un n manque.
AL
Le nombre d'octets est en fait 420, inférieur à celui indiqué.
Ray
1

Python 3, (503 octets)

Compressez le tableau à l'aide de bzip2, puis utilisez l'encodage ascii85 pour stocker le résultat. Le tableau est:

zéro
un
deux
trois
quatre
cinq
...
cent

Méthode très naïve, mais ce n'est pas si mal.

Golfé

import bz2,base64 as B
print(bz2.decompress(B.a85decode('6<\\%_0gSqh;d"=$\\VU:fOjTBn&3p:MiVu^S+:%s4!Q6o8\\8%r<Bp,5\\LT&Q+19!OmJC@3n\'bD<]UHekq<8OP<;]9BZ,;>836X4<[@KJ,)FsD^8j9Q=]O]&/8\'rjSK&0Sh0W[ru0E0!!M-tL69NZF6N\'Lc#$Q=?S_P0+uEZP"[H;%Ucch??nYC76\'k<)isZIBqqOKi(,IHp""^8d/EqRpc_I<IRj[\'4KB`/."%5,"pjr&27q+&t.6J+ik=Jdd2A)j]\'jt5ts0>:sr9.@E>V0F9L?9r&pX\'E.NUP:r&?>\'*(gKmd;/1QkUb*1&JhfWiE7Kl,P,o1go+.3O&l))Y,$/PO)%"al^4H2,n-l\\PuM!W1rBB9t.,U>DhAs83burMn(%%-qHG<gr+^')).decode().split('\n')[int(input())])

Non golfé

import bz2, base64
s = '6<\\%_0gSqh;d"=$\\VU:fOjTBn&3p:MiVu^S+:%s4!Q6o8\\8%r<Bp,5\\LT&Q+19!OmJC@3n\'bD<]UHekq<8OP<;]9BZ,;>836X4<[@KJ,)FsD^8j9Q=]O]&/8\'rjSK&0Sh0W[ru0E0!!M-tL69NZF6N\'Lc#$Q=?S_P0+uEZP"[H;%Ucch??nYC76\'k<)isZIBqqOKi(,IHp""^8d/EqRpc_I<IRj[\'4KB`/."%5,"pjr&27q+&t.6J+ik=Jdd2A)j]\'jt5ts0>:sr9.@E>V0F9L?9r&pX\'E.NUP:r&?>\'*(gKmd;/1QkUb*1&JhfWiE7Kl,P,o1go+.3O&l))Y,$/PO)%"al^4H2,n-l\\PuM!W1rBB9t.,U>DhAs83burMn(%%-qHG<gr+^'
table = bz2.decompress(base64.a85decode(s)).decode().split('\n')
num = int(input())
print(table[num])

Prime

Pouvez-vous trouver le mot "Vim" dans la chaîne compressée?

Rayon
la source
1
J'aime bien Sh0W. Impossible de trouver Vim, vous non plus.
tomsmeding
@tomsmeding Quel dommage! Vim a disparu après mon dernier montage.
Ray
1

Frapper, 456 440 421 408

Suppose une entrée valide (entier de 0 à 100 avec n'importe quel nombre de zéros non significatifs).

v=`sed 's/0*//'<<<$1`
f=('' dix vingt trente quarante cinquante soixante soixante-dix quatre-vingts quatre-vingt-dix)
s=('' ' et un' -deux -trois -quatre -cinq -six -sept -huit -neuf)
o=${f[${v: -2:1}]}${s[${v: -1:1}]}
[ "${o:0:1}" = \  ]&&o=un
((v>99))&&o=cent
sed 's/^-//
s/s-/-/
s/s et /-/
s/dix et un/onze/
s/di.*ux/douze/
s/d.*s$/treize/
s/d.*re/quatorze/
s/d.*q/quinze/
s/di.*ix/seize/'<<<${o:-zéro}

la source
1

JavaScript 459 (sans boîtier Camel)

@ edc65 ne peut pas vous prendre ça ...;)

A="0un0deux0trois0quatre0cinq0six0sept0huit0neuf0dix0onze0douze0treize0quatorze0quinze0seize0dix-sept0dix-huit0dix-neuf".split(0);S="soixante";Q=A[4]+"-vingt";T=10;V=20;N=59;for(b=5;1<b--;)for(c=V;c--;)X=b*V+c,A[X]=[,["vingt","trente"],["quarante","cinquante"],[S,S],[Q,Q]][b][c/T|0]+(X%T?X>N?X%V==T?"-dix":"":"":"")+(1>X%T?"":(1==X%(X>N?V:T)|71==X)&81!=X?" et ":"-")+(X>N&X%V==T?"-dix":A[c%(X>N?V:T)]);A[0]="zéro";A[80]+="s";A[100]="cent";alert(A[prompt()])

WallyWest
la source