Scrivi i numeri in francese


23

C'è stata una sfida a convertire un numero al suo numero in inglese , ma era troppo semplice. Dato un numero compreso tra 0 e 100, il tuo compito è produrre il numero corrispondente in francese. Il sistema numerico francese ha una logica più complessa rispetto a quella inglese:

Numero numerico
---------------
 0 zéro (notare l'accento)
 1 un
 2 deux
 3 trois
 4 quatre
 5 cinq
 6 sei
 7 sett
 8 huit
 9 neuf
10 dix
11 onze
12 douze
13 treize
14 quatorze
15 quinze
16 cogliere
17 dix-sett (letteralmente dieci sette)
18 dix-huit
19 dix-neuf
20 vingt
21 vingt et un (nessun trattino)
22 vingt-deux
...
30 trente
...
40 quarante
...
50 cinquante
...
60 soixante
...
70 soixante-dix (letteralmente sessanta dieci)
71 soixante et onze
...
80 quatre-vingts (nota la s; letteralmente quattro anni venti)
81 quatre-vingt-un (nota i trattini)
...
90 quatre-vingt-dix
91 quatre-vingt-onze
...
99 quatre-vingt-dix-neuf (4 * 20 + 10 + 9)
100 cent

Per un elenco completo, seguire http://quizlet.com/996950/ ( http://www.webcitation.org/6RNppaJx0 ).

Ulteriori regole / spiegazioni

  • Ci sarà sempre un trattino tra le parole EXCEPT quando il numero termina con 1.
  • Quando finisce numero in 1, la parola et (che significa e viene aggiunto) prima che l' ONU o onze . (31 = trente et un)
  • Tuttavia, 81 e 91 sono formattati allo stesso modo degli altri numeri. (81 = quatre-vingt-un)
  • A 60, il sistema passa dalla base 10 alla base 20.
  • Ci sono alcune piccole discrepanze in tutto il web in merito; fare riferimento all'elenco collegato sopra per domande.
  • Non sono consentite scappatoie vietate per impostazione predefinita .
  • Non è consentito l'utilizzo di una fonte esterna come un sito Web, nonché di biblioteche, API, funzioni o simili che convertono i numeri in numeri o li traducono in francese.
  • Questo è , quindi vince la risposta con il minor numero di byte.
  • Se disponibile, si prega di collegarsi a un compilatore online per consentire un facile test del codice.

Ingresso

  • L'input deve essere preso da qualunque sia la tua lingua. (STDIN, riga di comando, ecc.)
  • L'input sarà una singola stringa, costituita da un numero intero compreso tra 0 e 100 inclusi (zero iniziali facoltativi).
  • Puoi presumere che l'input sarà sempre ben formato.

Produzione

  • Il risultato deve essere inviato al metodo più conveniente per la tua lingua. (STDOUT, finestra di dialogo, ecc.)
  • Il caso non ha importanza nell'output.

Esempi

Metti alla prova il tuo codice rispetto a questi:

Input Output
-------------
0 zéro
18 dix-huit
51 cinquante et un
80 quatre-vingts
91 quatre-vingt-onze
99 quatre-vingt-dix-neuf

3
Si noti che i belgi francofoni usano "septante", "octante" e "nonante" invece di soixante-dix, quatre-vingts, quatre-vingt-dix. Dovrebbe essere usato nell'antica colonia belga.
Emmanuel,

8
+1 per il genio di farlo in francese. Come disse un mio collega tedesco: "I tedeschi dicono i numeri all'indietro. Ma per capire il francese, hai bisogno di una calcolatrice".
Level River St

1
Sembra che zéro sia l'unico numero accentato nell'intervallo 0-100. Questo non è un carattere ASCII standard. Suppongo che qualsiasi formato (code page 437, UTF-8, ecc.) In grado di emettere questo carattere sia accettabile.
Level River St

1
@Martin Lo stato delle regole "Puoi presumere che l'input sia sempre ben formato", quindi input> 100 può comportare qualsiasi comportamento.
NinjaBearMonkey

3
Non c'è assolutamente alcuna logica dietro il sistema francese. Sono sicuro che c'è un errore nel 99% dei controlli francesi, questo è ancora più complicato dopo i 100. Anche la congiunzione è un incubo. Fidati di me, sono francese.
Michael M.

Risposte:


7

JavaScript (ES6) 318 321

Modifica bug fix (gestione degli 0 iniziali) e giocava ancora a golf

Ringraziamo il trucco del caso del cammello @ Core1024

Con input / output tramite 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')))

Come funzione testabile

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

Per eseguire il test nella console 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')

Uscita di prova

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-set, 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-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-Quatorze, 96: Quatre-Vingt-Seize, 97: Quatre-Vingt-Dix-sett, 98: Quatre-Vingt-Dix-huit, 99: Quatre-Vingt-Dix-neuf, 
"Cent"

2
Fantastico trucco con la custodia del cammello!
tomsmeding

@tomsmeding davvero fantastico, quindi ovviamente non ideato da me (credito aggiunto in post)
edc65

@ edc65 Ti dispiace se provo a migliorare la mia risposta di Ruby con quello? Non ho nemmeno visto che l'output senza distinzione tra maiuscole e minuscole è consentito quando ho scritto il mio. ^^
Martin Ender,

@ MartinBüttner certo che puoi
edc65

6

Haskell, 390 byte

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

Ungolfed

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

I linguaggi di programmazione funzionale sono abbastanza adatti per questo lavoro.


Avere un voto, eri più veloce di me. Potresti voler sostituire il tuo principale con main=interact$f.reade salvare alcuni personaggi.
gxtaillon,

@gxtaillon Sì, ho dimenticato interact. Aggiornato.
Ray

5

Rubino, 333 byte

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

Sono principalmente solo due tabelle di ricerca e un gruppo di operatori ternari che codificano tutte le regole strane e ti dicono quale tabella di ricerca utilizzare quando. Fammi sapere se vuoi saperne di più. ;)


1
Odio essere pignolo, ma 80dovrebbe produrre quatre-vingts, con una s alla fine.
NinjaBearMonkey

@hsl riparato e abbreviato un po '.
Martin Ender,

5

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

Grazie a grc, Ray e isaacg per il loro aiuto nel processo di golf.

Il codice consiste nella definizione iniziale del dizionario e nella comprensione di un elenco che riempie gli spazi vuoti con la giunzione degli elementi del dizionario.

Puoi controllare il codice online su 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()]

I miei ultimi tentativi di giocare a golf con questo codice sono stati di rinunciare al processo di generazione e, con quella riduzione, ho perfezionato la funzione per generare semplicemente il numero richiesto sul posto. Tuttavia, poiché i numeri degli anni '60 e '80 necessitano di elementi non calcolati, la lotta è stata quella di creare una tale funzione riducendo il codice.


3
È possibile utilizzare r=range, questo trucco per le linee 2 e 3, e solo uno spazio per l'indentazione. E puoi salvare 65 byte cond=dict(zip(r(17)+r(20,70,10)+[80,100],'zéro un deux ... quatre-vingt cent'.split()))
grc

Il r=rangetrucco di cui ero a conoscenza, ma ho dimenticato di aggiungerlo quando ho scritto la prima revisione. Tutto il resto era relativamente nuovo per me, quindi grazie sono in ordine. Una nota però, il codice non funziona su Python 3.x se l' printistruzione non viene trasformata in una funzione e le rfunzioni nel dict vengono trasformate in elenchi.
Doktoro Reichard,

In Python 2 non è necessario int(input()), input()è abbastanza.
Ray,

1
Alcuni ulteriori suggerimenti: penso che se si mette b=a/60*10+10in f(a)allora si potrebbe utilizzare a-a%be a%bper le chiavi del dizionario. Inoltre, non è necessario lo spazio 1 ore la quarta riga può essere accorciata [f(v)for v in r(100)if v not in d]. Non ho provato nulla di tutto questo però.
GRC

1
if v not in d-> if(v in d)<1salva un personaggio. Se il punto e virgola separa le due parti della funzione, è possibile inserire tutto su una riga.
isaacg

4

Python - 392 byte

Ha un elenco con numeri di base che utilizza per generare gli altri numeri. La maggior parte della logica di generazione è nella comprensione dell'elenco alla riga 2, usando l'indicizzazione dell'elenco per i condizionali. Una volta generato l'elenco, cerca il numero immesso e lo stampa.

Modifica: abbreviato da 426 byte usando il suggerimento di 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())])

1
Puoi salvare 23 byte cona='_un_deux_trois ... quinze_seize'.split('_')
grc

5
C'è un errore di battitura: ciquante , manca un n .
AL

Il conteggio dei byte è in realtà 420, inferiore a quanto dichiarato.
Ray,

1

Python 3, (503 byte)

Comprimi la tabella usando bzip2 e quindi usa la codifica ascii85 per memorizzare il risultato. La tabella è:

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

Metodo molto ingenuo, ma non è poi così male.

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

Ungolfed

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

indennità

Riesci a trovare la parola "Vim" nella stringa compressa?


1
Mi piace abbastanza Sh0W. Impossibile trovare Vim, né tu.
tomsmeding

@tomsmeding Che peccato! Vim è scomparso dopo la mia ultima modifica.
Ray

1

bash, 456 440 421 408

Presuppone un input valido (numero intero compreso tra 0 e 100 con qualsiasi numero di zeri iniziali).

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}

1

JavaScript 459 (nessun involucro di cammello)

@ edc65 non puoi prenderlo da te ...;)

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.