Разобрать цифры по-французски

23

Была проблема с преобразованием числа в цифру на английском языке , но это было слишком просто. Для числа 0–100 ваша задача - вывести соответствующую цифру на французском языке. Французская система счисления имеет более сложную логику по сравнению с английской:

Номер цифра
---------------
 0 зеро (обратите внимание на акцент)
 1 ун
 2 deux
 3 тройки
 4 кватра
 5 фунтов
 6 шесть
 7 сентября
 8 huit
 9 новых
10 дикс
11 онзе
12 дуз
13 трейз
14 кватерза
15 лебед
16 захватить
17 Дикс-сент (буквально десять семь)
18 Дикс-Хуит
19 Дикс-Нёф
20 вингт
21 vingt et un (без дефисов)
22 вингт-де
...
30 трентов
...
40 каранте
...
50 cinquante
...
60 сойксанте
...
70 сойксанте-дикс (буквально шестьдесят десять)
71 soixante et onze
...
80 quatre-vingts (обратите внимание, буквально четыре двадцатых)
81 quatre-vingt-un (обратите внимание на дефисы)
...
90 quatre-vingt-dix
91 quatre-vingt-onze
...
99 quatre-vingt-dix-neuf (4 * 20 + 10 + 9)
100 центов

Для получения полного списка следуйте http://quizlet.com/996950/ ( http://www.webcitation.org/6RNppaJx0 ).

Дальнейшие правила / объяснения

  • Между словами всегда будет дефис, за исключением того, что число заканчивается на 1.
  • Когда число заканчивается на 1, слово et (означающее и ) добавляется перед un или onze . (31 = Тренте и др.)
  • Однако 81 и 91 отформатированы так же, как и другие числа. (81 = quatre-vingt-un)
  • В 60 система переключается с базы 10 на базу 20.
  • В Интернете есть небольшие несоответствия по этому поводу; обратитесь к списку, связанному выше для вопросов.
  • Лазейки, которые по умолчанию запрещены , не допускаются.
  • Использование внешнего источника, такого как веб-сайт, а также любых библиотек, API, функций и т. П., Которые преобразуют числа в цифры или переводят на французский, недопустимо.
  • Это , поэтому выигрывает ответ с наименьшим количеством байтов.
  • Если возможно, обратитесь к онлайн-компилятору, чтобы облегчить тестирование вашего кода.

вход

  • Входные данные должны быть взяты из вашего языка. (STDIN, командная строка и т. Д.)
  • Входные данные будут одной строкой, состоящей из целого числа от 0 до 100 включительно (начальные нули необязательны).
  • Вы можете предположить, что входные данные всегда будут правильными.

Выход

  • Результат будет выведен наиболее удобным для вас языком. (STDOUT, диалоговое окно и т. Д.)
  • Дело не имеет значения в выводе.

Примеры

Протестируйте свой код на соответствие этим:

Ввод, вывод
-------------
0 зеро
18 Дикс-Хуит
51 cinquante et un
80 quatre-vingts
91 quatre-vingt-onze
99 quatre-vingt-dix-neuf
NinjaBearMonkey
источник
3
Обратите внимание, что франкоговорящие бельгийцы используют «septante», «octante» и «nonante» вместо «soixante-dix», «quatre-vingts», «quatre-vingt-dix». Это следует использовать в древней бельгийской колонии.
Эммануэль
8
+1 за гений сделать это по-французски. Как сказал мой немецкий коллега: «Немцы говорят цифры задом наперед. Но чтобы понимать французов, нужен калькулятор».
Уровень Река St
1
Похоже, что 0 - единственное акцентированное число в диапазоне 0-100. Это не стандартный символ ASCII. Я предполагаю, что любой формат (кодовая страница 437, UTF-8 и т. Д.), Который может выводить этот символ, является приемлемым.
Уровень Река St
1
@Martin Правила гласят: «Можно предположить, что входные данные всегда будут правильно сформированы», поэтому ввод> 100 может привести к любому поведению.
NinjaBearMonkey
3
За французской системой нет абсолютно никакой логики. Я уверен, что есть ошибка в 99% французских проверок, это еще сложнее после 100. Сопряжение - это тоже кошмар. Поверь мне, я француз.
Майкл М.

Ответы:

7

JavaScript (ES6) 318 321

Редактировать Исправлена ошибка (управление ведущими 0s) и golfed более

Кредит на верблюжий трюк @ Core1024

С вводом / выводом через всплывающее окно

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

В качестве тестируемой функции

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

Для тестирования в консоли FireFox или 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')

Тестовый вывод

0: Zero, 1: Un, 2: Deux, 3: Trois, 4: Quatre, 5: Cinq, 6: Six, 7: Sept, 8: Huit, 9: Neuf,
10: Дикс, 11: Онзе, 12: Дузе, 13: Треизе, 14: Кваторзе, 15: Куинзе, 16: Захватить, 17: Дикс-сент, 18: Дикс-Хуит, 19: Дикс-Нёф,
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: Тренте-Нёф,
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: Сойшанте-Дикс-Хуит, 79: Сойшанте-Дикс-Нёф,
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
источник
2
Прикольный трюк с верблюжьим чехлом!
Томсминг
@tomsmeding действительно круто, так что, очевидно, я не придумал (добавлено в пост)
edc65
@ edc65 Вы не возражаете, если я попытаюсь улучшить свой ответ Ruby с этим? Я даже не видел, что нечувствительный к регистру вывод разрешен, когда я написал свой. ^^
Мартин Эндер
@ MartinBüttner, конечно, вы можете
edc65
6

Haskell, 390 байт

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

Функциональные языки программирования вполне подходят для этой работы.

луч
источник
Воздержитесь, вы были быстрее меня. Вы можете заменить основной main=interact$f.readи сохранить несколько символов.
gxtaillon
@gxtaillon Да, я забыл interact. Обновлено.
Рэй
5

Рубин, 333 байта

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

В основном это всего две справочные таблицы и куча троичных операторов, которые кодируют все странные правила и сообщают, какую справочную таблицу использовать, когда. Дайте мне знать, если вы хотите узнать больше. ;)

Мартин Эндер
источник
1
Ненавижу быть придирчивым, но 80должен вывести quatre-vingts, с s в конце.
NinjaBearMonkey
@hsl исправлен и немного укорочен.
Мартин Эндер
5

Python - 344 (348) (380) (445) (537) байтов

Спасибо grc, Ray и isaacg за помощь в процессе игры в гольф.

Код состоит из начального определения словаря и понимания списка, которое заполняет пробелы соединением элементов словаря.

Вы можете проверить код онлайн на 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()]

Моими последними попытками использовать этот код был отказ от процесса генерации, и с этим сокращением я усовершенствовал функцию, чтобы просто генерировать запрошенное число на месте. Однако, поскольку числа 60 и 80-х нуждаются в неисчисляемых элементах, борьба заключалась в создании такой функции при уменьшении кода.

Доктор Рейхард
источник
3
Вы можете использовать r=range, этот трюк для линий 2 и 3, и только одно место для отступа. И вы можете сэкономить 65 байт сd=dict(zip(r(17)+r(20,70,10)+[80,100],'zéro un deux ... quatre-vingt cent'.split()))
grc
r=rangeТрюк я был в курсе, но забыл добавить его , когда я написал 1 - й пересмотр. Все остальное было относительно новым для меня, так что спасибо в порядке. Обратите внимание, что код не работает на Python 3.x, если только printоператор не превращен в функцию, а rфункции в dict не превращены в списки.
Доктор Рейхард
В Python 2 вам не нужно int(input()), input()достаточно.
Рэй
1
Еще несколько советов: Я думаю , что если вы положили b=a/60*10+10в f(a)то вы можете использовать a-a%bи a%bдля словаря ключей. Кроме того, вам не нужно пространство 1 or, и 4-я строка может быть сокращена до [f(v)for v in r(100)if v not in d]. Я не пробовал ничего из этого, хотя.
GRC
1
if v not in d-> if(v in d)<1сохраняет персонажа. Если вы разделяете точки с запятой двумя частями своей функции, вы можете поместить все это в одну строку.
Исаак
4

Python - 392 байта

У него есть список с базовыми числами, которые он использует для генерации других чисел. Большая часть логики генерации находится в понимании списка в строке 2 с использованием индексации списка для условных выражений. Как только список сформирован, он ищет введенный номер и печатает его.

Изменить: Сокращенный от 426 байтов, используя чаевые 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
источник
1
Вы можете сохранить 23 байта с помощьюa='_un_deux_trois ... quinze_seize'.split('_')
grc
5
Есть опечатка: ciquante , а n отсутствует.
AL
Ваш байт на самом деле 420, меньше, чем указано.
Рэй
1

Python 3, (503 байта)

Сожмите таблицу, используя bzip2, а затем используйте кодировку ascii85 для сохранения результата. Таблица является:

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

Очень наивный метод, но все не так плохо.

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

бонус

Можете ли вы найти слово "Vim" в сжатой строке?

луч
источник
1
Я очень хотел Sh0W. Не могу найти Вим, как и ты.
Томсминг
@tomsmeding Как жаль! Vim исчез после моего последнего редактирования.
Рэй
1

Bash, 456 440 421 408

Предполагается допустимый ввод (целое число от 0 до 100 с любым количеством ведущих нулей).

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 (без корпуса верблюда)

@ edc65 не может отнять это у тебя ...;)

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

Уолли Уэст
источник