Ти романізатор, дитино


38

Романізація японської мови - це перетворення японського тексту в латинські символи. У цьому виклику вам буде надано рядок японських символів як вхідний і очікується перетворення їх у правильний рядок ASCII.

Що вам потрібно знати

У японській мові є три системи письма: хірагана (кривава, яка використовується для коротких слів), катакана (кут-у, яка використовується для звуків і слів, запозичених з інших мов) і кандзі (щільні символи спочатку з китайської). У цьому виклику ми будемо турбуватися лише про хірагану.

У навчальній програмі хірагана 46 символів. Кожен символ являє собою склад. Символи впорядковані за першим звуком (приголосний) та другим звуком (голосним). Стовпці в порядку є aiueo.

 : あいうえお
k: かきくけこ
s: さしすせそ
t: たちつてと
n: なにぬねの
h: はひふへほ
m: まみむめも
y: や ゆ よ
r: らりるれろ
w: わ   を
N: ん

(якщо скопіювати та вставити цю таблицю, зауважте, що я використовував ідеографічні простори U + 3000 для пробілу y та w)

Так, наприклад, あ と め повинен отримати вихід atome. Перший персонаж є a, другий - toтретій me.

Винятки

Як і будь-яка гарна мова, японська має винятки зі своїх правил, а таблиця хірагани - кілька. Ці символи вимовляються дещо інакше, ніж їх розташування в таблиці означало б:

し: shi, не si
ち: chi, не ti
つ: tsu, не tu
ふ: fu, ніhu

Дакутен ゛

Слово «дакутен» означає «каламутний знак»: дакутен перетворює звуки у їхні озвучені еквіваленти (як правило); наприклад, かkaперетворюється на か ゛ga. Повний список змін:

kg
sz
td
hb

Винятки також змінюються: し ゛: ji(або zhi), не zi
ち ゛: ji, не di
つ ゛: dzu, не du
(ふ ゛ діє так, як ви очікували; це не виняток)

Хандакутен - це додатковий символ ゜, який застосовується до hрядка. Якщо розміщується після символу, він змінює звук персонажа на, pа не b.

Як дакутен, так і хандакутен даватимуться як окремі символи. Вам не потрібно буде мати справу з заздалегідь складеними формами або об'єднаними символами.

Маленькі персонажі

Нарешті, є невеликі версії деяких персонажів. Вони змінюють персонажів, що надходять до них або після них.

ゃ ゅ ょ

Це невеликі форми ya, yuі yo. Вони розміщуються лише після звуків у iколоні; вони видаляють iі додають звук. Отже, き や перетворюється на kiya; き ゃ перетворюється на kya.

Якщо розміщено після chiабо shi(або їх документи, що містяться в документах), також yвидаляється. し ゆ є shiyu; し ゅ є shu.

Останнє, з чим вам доведеться зіткнутися, - це мале tsu. っ подвоює приголосний, що йде після нього, незважаючи ні на що; він більше нічого не робить. Наприклад, き た є kita; き っ た є kitta.

Підсумок, вхід та вихід

Ваша програма повинна вміти транслітерувати: 46 основних гірагани, форми їх дакутенів та хандакутен та їх комбінації з малими символами.

Не визначена поведінка включає: малий ya, yuа yoне після символу з i, малий tsuна кінці рядка, дакутен на непорушеному символі, хандакутен на не pсимволі та все інше, що не згадується у вищевказаній специфікації / вступі.

Ви можете вважати, що всі введення є дійсними та містять лише японські символи, згадані вище.

Справа не має значення у виході; Ви можете також замінити rз lабо одинаком nз m. Вихід може мати один пробіл між кожним складом або взагалі не мати пробілів.

Це : найкоротший код у байтах виграє.

Випробування

Багато тестів для кожної окремої частини наведено у специфікації. Деякі додаткові випадки:

ひ ら か ゛ な → hiragana

か た か な → katakana

た ゛ い き ゛ ゃ く て ん さ い は ゛ ん → daigyakutensaiban

ふ ゜ ろ く ゛ ら み ん く ゛ は ゜ す ゛ る う と ゛ こ ゛ る ふ → puroguramingupazurucoudogorufu

か ゛ ん ほ ゛ っ て → ganbatte

Примітки

  • Я не знаю багато японського, окрім того, що тут написав. Будь ласка, дайте мені знати, чи я допустив помилки.

  • Я спочатку планував включити катакану (тому мій тест на транслітерацію з англійської мови міг бути дещо точнішим), але це було б занадто багато для проблеми з кодовим гольфом.

  • Імена Unicode включають транслітерацію кожного символу окремо, але без винятку. Це може вам чи не бути корисним.

  • Завдяки squeamishossifrage за виправлення двох помилок!

  • Мені шкода, якщо це занадто довго; Я намагався вкласти у виклик більшість вигадків хірагани, але деякі речі (наприклад, маленька хірагана лише для голосних, зміна n на m перед деякими приголосними та позначка повторення) повинні були бути вирізані, щоб виклик був керованим.

  • Мені зовсім не шкода звання. Це шедевр.


1
Для чого повинен бути результат きっった?
lirtosiast

@Thomas: це неправильний ввід. Вихід може бути будь-яким, що ви хочете.
Deusovi

1
має っしбути sshiчи shshi?
lirtosiast

2
I'm not at all sorry for the title. It's a masterpiece.Повноцінне
Засуджене

3
@Fatalize Не потрібно доносити сюди свої анти-Брітні. Незважаючи на те, що я особисто можу бути більш шанувальником J-Lo, я не збираюся скласти чудову головоломку над цим.
напів зовнішній

Відповіді:


7

Python 2, 638 байт

import unicodedata
s=input()
k=[0x309B,0x309C,0x3063]
m=[0x3083,0x3085,0x3087]
e={0x3057:'shi',0x3061:'chi',0x3064:'tsu',0x3075:'fu'}
d={0x3057:'ji',0x3061:'ji',0x3064:'dzu'}
D=dict(zip('ksth','gzdb'))
f=lambda c:unicodedata.name(c).split()[-1].lower()if ord(c)not in e else e[ord(c)]
g=lambda c:d[c]if c in d else D[f(c)[0]]+f(c)[1:]
R=[]
r=[]
t=[]
i=0
while i<len(s):
 c=ord(s[i])
 if c==k[0]:R[-1]=g(s[i-1])
 elif c==k[1]:R[-1]='p'+R[-1][1:]
 elif c in m:R[-1]=R[-1][:-1];n=f(s[i]);R+=[n[1:]]if r[-1]in[0x3057,0x3061]else[n];r+=[c]
 elif c==k[2]:t+=[len(R)]
 else:R+=[f(s[i])];r+=[c]
 i+=1
for i in t:R[i]=R[i][0]+R[i]
print ''.join(R)

Приймає введення як рядок unicode.

Перевірте це на Ideone


1
Ви можете врятувати непомітний бай, перейшовши print ''.join(R)наprint''.join(R)
Zacharý

6

Python 2, 447 байт

import unicodedata as u
r=str.replace
i=''.join('x'*('SM'in u.name(x)or ord(x)==12444)+u.name(x)[-2:].strip()for x in raw_input().decode('utf-8'))
for a,o in zip('KSTH','GZDB'):
    for b in'AEIOU':i=r(r(i,a+b+'xRK','P'+b),a+b+'RK',o+b)
for a,b,c,d in zip('STDZ',('SH','CH','J','J'),'TDHH',('TS','DZ','F','F')):i=r(r(i,a+'I',b+'I'),c+'U',d+'U')
for a in'CH','SH','J':i=r(i,a+'IxY',a)
for a in'BCDFGHJKMNPRSTWYZ':i=r(i,'xTSU'+a,a+a)
print r(i,'Ix','')

Це вимагає безпосередньо введення Unicode, через що я втратив кілька байт через те, decode('utf-8')але я думаю, що це більше відповідає духу виклику.

Я почав із заміни кожного символу двома останніми символами його однокодового імені, як це запропоновано в примітках головоломки. На жаль, це не розрізняє альтернативні версії одного символу, тому мені довелося зробити некрасивий хакер, щоб додати "x" перед маленькими символами та handakuten.

Решта циклів для циклів - це лише виправлення винятків, щоб:

  1. перший для циклу перетворює дакутен і хандакутен у правильні приголосні;
  2. другий для циклу займається винятками хірагани ши, чі, цу і фу;
  3. третє для циклу має справу з винятками перед малим символом y (наприклад, sha, jo);
  4. четверте для циклу має справу з подвоєнням приголосних після невеликого цу.
  5. заключний рядок стосується малих y-.

Я б хотів, щоб я міг поєднати більше кроків, але в деяких випадках кроки потрібно виконувати, щоб уникнути конфліктів.

Спробуйте в Інтернеті! (багатолінійну версію з більшою кількістю прикладів можна знайти тут ).



Ласкаво просимо до PPCG. Дуже приємне перше рішення :)
Shaggy

Перетворіть чотири пробіли навпроти for b in'AEIOU'у вкладку або один пробіл, щоб зберегти 3 байти. Можливо, ви також зможете скористатися from unicodedata import*для збереження деяких байтів - не впевнений.
Стівен

4

Swift 3, 67 64 символи

нехай r = {(s: String) у s.applyingTransform (.toLatin, зворотний: false)}

let r={(s:String)in s.applyingTransform(.toLatin,reverse:false)}

3
Справді, вбудований, Свіфт має для цього БУДІВЕЛЬ?
Zacharý

Ви взагалі не знаєте Свіфта, але чи можете ви рубати пробіли після s:String)і .toLatin,?
Yytsi

@TuukkaX, добре помічений!
idrougge

@ Zacharý, добре Foundation.
idrougge

3

Python 3 , 259 байт

import re,unicodedata as u
s=re.sub
n=u.normalize
k,*r=r'NFKC DZU DU TSU TU \1\1 SM.{6}(.) \1 (CH|J|SH)Y \1 ISMALL.(Y.) CHI TI JI [ZD]I SHI SI FU HU'.split()
t=''.join(u.name(c)[16:]for c in n(k,s(' ','',n(k,input()))))
while r:t=s(r.pop(),r.pop(),t)
print(t)

Спробуйте в Інтернеті!

Пояснення

Нам пощастило з цим форматом введення! Подивіться, що станеться, якщо я передаю вхід через нормалізацію NFKC :

>>> nfkc = lambda x: u.normalize('NFKC', x)
>>> [u.name(c) for c in 'は゛']
['HIRAGANA LETTER HA', 'KATAKANA-HIRAGANA VOICED SOUND MARK']
>>> [u.name(c) for c in nfkc('は゛')]
['HIRAGANA LETTER HA', 'SPACE', 'COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK']

Дакутен заміняється пробілом і комбінуючим дакутеном. Тепер цей простір - це все, що відокремлює は від його дакутену. Тож ми позбуваємося цього і знову нормалізуємося :

>>> [u.name(c) for c in nfkc(nfkc('は゛').replace(' ', ''))]
['HIRAGANA LETTER BA']

Бінго. П'ятий рядок перетворює вхід на щось подібне

KONOSUBARASIISEKAINISISMALL YUKUHUKUWO

Тоді ми застосовуємо 9 нудних заміни регулярних виразів, набитих r, і ми закінчили:

KONOSUBARASHIISEKAINISHUKUFUKUWO

(Джонатан Френч врятував 4 байти, писав import re,unicodedata as uзамість import re;from unicodedata import*. Спасибі!)


Зловживають нормалізацією для розваги та отримання прибутку. Це прекрасно.
Тім Педерік

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.