Deletrea los números en francés

23

Hubo un desafío para convertir un número a su número en inglés , pero eso fue demasiado sencillo. Dado un número 0–100, su tarea es generar el número correspondiente en francés. El sistema de numeración francés tiene una lógica más compleja que el inglés:

Numeral Numero
---------------
 0 zéro (nota el acento)
 1 un
 2 deux
 3 trois
 4 quatre
 5 cinq
 6 seis
 7 sept
 8 huit
 9 neuf
10 dix
11 onze
12 douze
13 treize
14 quatorze
15 quinze
16 apoderarse
17 dix-sept (literalmente diez siete)
18 dix-huit
19 dix-neuf
20 vingt
21 vingt et un (sin guiones)
22 vingt-deux
...
30 trente
...
40 quarante
...
50 cinquante
...
60 soixante
...
70 soixante-dix (literalmente sesenta y diez)
71 soixante et onze
...
80 quatre-vingts (tenga en cuenta la s; literalmente cuatro años veinte)
81 quatre-vingt-un (tenga en cuenta los guiones)
...
90 quatre-vingt-dix
91 quatre-vingt-onze
...
99 quatre-vingt-dix-neuf (4 * 20 + 10 + 9)
100 centavos

Para obtener una lista completa, siga http://quizlet.com/996950/ ( http://www.webcitation.org/6RNppaJx0 ).

Otras reglas / explicaciones

  • Siempre habrá un guión entre las palabras EXCEPTO cuando el número termine en 1.
  • Cuando el número termina en 1, la palabra et (significado y ) se agrega antes de un u onze . (31 = trente et un)
  • Sin embargo, 81 y 91 tienen el mismo formato que los otros números. (81 = quatre-vingt-un)
  • A los 60, el sistema cambia de la base 10 a la base 20.
  • Hay algunas discrepancias menores en la web sobre esto; consulte la lista vinculada anteriormente para preguntas.
  • Las lagunas prohibidas por defecto no están permitidas.
  • No se permite el uso de una fuente externa como un sitio web, así como bibliotecas, API, funciones o similares que conviertan números en números o traduzcan al francés.
  • Este es el , por lo que gana la respuesta con la menor cantidad de bytes.
  • Si está disponible, enlace a un compilador en línea para permitir una prueba fácil de su código.

Entrada

  • La entrada se tomará de la forma en que su idioma tome entrada (STDIN, línea de comando, etc.)
  • La entrada será una sola cadena, que consta de un número entero entre 0 y 100 inclusive (ceros iniciales opcionales).
  • Puede suponer que la entrada siempre estará bien formada.

Salida

  • El resultado se enviará al método más conveniente para su idioma. (STDOUT, cuadro de diálogo, etc.)
  • El caso no importa en la salida.

Ejemplos

Pruebe su código contra estos:

De entrada y salida
-------------
0 zéro
18 dix-huit
51 cinquante et un
80 quatre-vingts
91 quatre-vingt-onze
99 quatre-vingt-dix-neuf
NinjaOsoMono
fuente
3
Tenga en cuenta que los belgas de habla francesa usan "septante", "octante" y "nonante" en lugar de soixante-dix, quatre-vingts, quatre-vingt-dix. Debería estar acostumbrado en la antigua colonia belga.
Emmanuel
8
+1 por el genio de hacer esto en francés. Como dijo un colega alemán: "Los alemanes dicen los números al revés. Pero para entender a los franceses, necesitas una calculadora".
Level River St
1
Parece que zéro es el único número acentuado en el rango 0-100. Este no es un carácter ASCII estándar. Supongo que cualquier formato (página de códigos 437, UTF-8, etc.) que pueda generar este carácter es aceptable.
Level River St
1
@Martin Las reglas establecen "Puede asumir que la entrada siempre estará bien formada", por lo que la entrada> 100 puede provocar cualquier comportamiento.
NinjaBearMonkey
3
No hay absolutamente ninguna lógica detrás del sistema francés. Estoy seguro de que hay un error en el 99% de los cheques franceses, esto es aún más complicado después de 100. La conjugación también es una pesadilla. Confía en mí, soy francés.
Michael M.

Respuestas:

7

JavaScript (ES6) 318 321

Editar corrección de errores (gestión de ceros iniciales) y jugar más golf

Crédito por el truco del caso camello @ Core1024

Con entrada / salida a través de una ventana emergente

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

Como una función comprobable

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

Para probar en la consola FireFox o 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')

Prueba de salida

0: Zéro, 1: Un, 2: Deux, 3: Trois, 4: Quatre, 5: Cinq, 6: Seis, 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: 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, 
"Centavo"
edc65
fuente
2
¡Genial truco con el estuche de camellos!
tomsmeding
@tomsmeding realmente genial, así que obviamente no fue ideado por mí (crédito adicional en la publicación)
edc65
@ edc65 ¿Te importa si trato de mejorar mi respuesta de Ruby con eso? Ni siquiera vi que la salida que no distingue entre mayúsculas y minúsculas está permitida cuando escribí el mío. ^^
Martin Ender
@ MartinBüttner, por supuesto que puedes
edc65
6

Haskell, 390 bytes

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

Sin 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

Los lenguajes de programación funcional son bastante adecuados para este trabajo.

Rayo
fuente
Ten un voto positivo, fuiste más rápido que yo. Es posible que desee reemplazar su principal con main=interact$f.ready guardar algunos caracteres.
gxtaillon
@gxtaillon Sí, lo olvidé interact. Actualizado.
Ray
5

Rubí, 333 bytes

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

En su mayoría, son solo dos tablas de búsqueda y un grupo de operadores ternarios que codifican todas las reglas extrañas y le indican qué tabla de búsqueda usar cuando. Avísame si quieres saber más. ;)

Martin Ender
fuente
1
Odio ser quisquilloso, pero 80debería mostrar quatre-vingts, con una s al final.
NinjaBearMonkey
@hsl arreglado y acortado un poco.
Martin Ender
5

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

Gracias a grc, Ray e Isaac por su ayuda en el proceso de golf.

El código consiste en la definición inicial del diccionario y una comprensión de la lista que completa los espacios en blanco con la unión de los elementos del diccionario.

Puede consultar el código en línea en 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()]

Mis últimos intentos de jugar golf en este código han sido renunciar al proceso de generación y con esa reducción perfeccionar la función para generar el número solicitado en el acto. Sin embargo, dado que los números de los años 60 y 80 necesitan elementos no calculados, la lucha ha sido crear dicha función mientras se disminuye el código.

Doktoro Reichard
fuente
3
Se podría utilizar r=range, este truco para las líneas 2 y 3, y sólo un espacio para el sangrado. Y puede guardar 65 bytes cond=dict(zip(r(17)+r(20,70,10)+[80,100],'zéro un deux ... quatre-vingt cent'.split()))
grc
El r=rangetruco lo conocía, pero olvidé agregarlo cuando escribí la primera revisión. Todo lo demás era relativamente nuevo para mí, así que gracias están en orden. Sin embargo, una nota, el código no funciona en Python 3.x a menos que la printdeclaración se convierta en una función y las rfunciones en el dict se conviertan en listas.
Doktoro Reichard
En python 2 no necesitas int(input()), input()es suficiente.
Ray
1
Algunos consejos más: creo que si se pone b=a/60*10+10en f(a)entonces se podría usar a-a%by a%bpara sus claves de diccionario. Además, no necesita espacio 1 or, y la cuarta línea se puede acortar [f(v)for v in r(100)if v not in d]. Sin embargo, no he probado nada de esto.
grc
1
if v not in d-> if(v in d)<1guarda un personaje. Si el punto y coma separa las dos partes de su función, puede ponerlo todo en una línea.
isaacg
4

Python - 392 bytes

Tiene una lista con números base que utiliza para generar los otros números. La mayor parte de la lógica de generación está en la comprensión de la lista en la línea 2, utilizando la indexación de lista para condicionales. Una vez que se genera la lista, busca el número ingresado y lo imprime.

Editar: acortado de 426 bytes con la punta 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
fuente
1
Puede guardar 23 bytes cona='_un_deux_trois ... quinze_seize'.split('_')
grc
55
Hay un error tipográfico: ciquante , falta una n .
AL
Tu conteo de bytes es en realidad 420, menos de lo indicado.
Ray
1

Python 3, (503 bytes)

Comprima la tabla usando bzip2 y luego use la codificación ascii85 para almacenar el resultado. La mesa es:

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

Método muy ingenuo, pero no es tan malo.

Golfed

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

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

Prima

¿Puedes encontrar la palabra "Vim" en la cadena comprimida?

Rayo
fuente
1
Me gusta bastante Sh0W. No pude encontrar a Vim, ni tú tampoco.
tomsmeding
@tomsmeding ¡Qué lástima! Vim desapareció después de mi última edición.
Ray
1

Golpetazo, 456 440 421 408

Asume una entrada válida (entero de 0 a 100 con cualquier número de ceros iniciales).

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}

fuente
1

JavaScript 459 (sin carcasa de camello)

@ edc65 no te lo puede quitar ...;)

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
fuente