Романізація корейської


12

Так, це в основному ти романізатор, дитина , але важче . як, спосіб складніше.

Вивчення корейської мови - ТРУД. принаймні для людини поза Азією. Але вони принаймні мають шанс навчитися, правда?

Що ти повинен робити

Вам видадуть корейську заяву. Наприклад, 안녕하세요. Ви повинні перетворити вхід на римську вимову. Для наведеного прикладу вихід може бути annyeonghaseyo.

Тепер це стає технічним

Корейський символ має три частини: Початковий приголосний, Голосний та Закінчуючий приголосний. Приголосний закінчення може не існувати в символі.

Наприклад, є (Починаючи приголосний) і (Голосний), і є (Починаючи приголосний), (Голосний) і (Закінчуючи приголосний).

Еверт приголосний і голосний має свою вимову. Вимова кожного приголосного полягає в наступному.

Korean                 ㄱ   ㄲ  ㄴ  ㄷ   ㄸ  ㄹ  ㅁ  ㅂ  ㅃ  ㅅ  ㅆ  ㅇ   ㅈ   ㅉ  ㅊ ㅋ  ㅌ   ㅍ  ㅎ
Romanization Starting   g   kk  n   d   tt  r   m   b   pp  s   ss  –   j   jj  ch  k   t   p   h
               Ending   k   k   n   t   –   l   m   p   –   t   t   ng  t   –   t   k   t   p   h

(- означає, що вимова не використовується або не використовується. Вам не доведеться їх обробляти.)

і вимова для кожного голосного наступна.

Hangul          ㅏ  ㅐ  ㅑ  ㅒ   ㅓ  ㅔ  ㅕ  ㅖ  ㅗ   ㅘ   ㅙ  ㅚ ㅛ  ㅜ  ㅝ  ㅞ  ㅟ   ㅠ  ㅡ   ㅢ ㅣ
Romanization    a   ae  ya  yae eo  e   yeo ye  o   wa  wae oe  yo  u   wo  we  wi  yu  eu  ui  i

Тепер це справжня важка частина

Вимова приголосного змінюється на приголосний закінчення раніше. Вимова кожного приголосного початку / кінця - наступне зображення. Дякую, Вікіпедія.  Якби цього не було, я мав би написати це все. (Не потрібно робити дефіс між вимовами. Її непотрібно. Якщо в клітині є дві або більше вимови, виберіть її. Якщо немає приголосного закінчення, використовуйте оригінальну вимову.)

Приклади

Korean => English
안녕하세요 => annyeonghaseyo
나랏말싸미 듕귁에달아 => naranmalssami dyunggwigedara  //See how the ㅅ in 랏 changes from 't' to 'n'

Приклад пропозиції вітається. Ви можете отримати відповіді на власні дані тут . (Я прошу в "Загальному тексті", переглянутому)


Чи завжди вхід складається з символів Unicode AC00-D7AF + пробіл?
Арнольд

1
Існує кілька спеціальних комбінацій ㅎ + X, які не виділені жовтим кольором (наприклад, ㅎ + ㅈ = ch). Це означає, що нам не потрібно їх підтримувати? (Крім того, roma "романізований", як t, а не h на знімку, що трохи заплутано.)
Арнольд

1
Тестові приклади: gist.github.com/perey/563282f8d62c2292d11aabcde0b94d2d Як говорить @Arnauld, у спеціальних комбінаціях є деякі дивацтва; це тести для всіх тих, що я знайшов у таблиці, незалежно від того, виділені вони чи ні. Там, де існує кілька варіантів, вони розділені пробілом. Жодні дефіси не використовуються, оскільки я очікую, що люди будуть їх гольфувати.
Тім Педерік

1
Я не бачу "Загальний текст" у запропонованому вами посиланні для перевірки вихідних даних; ти маєш на увазі "Загальні речі"? Якщо так, то який із трьох слід використати (Переглянуті, Маккун, Єльський)? Здається, жоден не відповідає вашому столу; наприклад, ㅈ, за яким ㄹ, має бути "nn" відповідно до вас, але є "tr" або "cl" на цьому посиланні. (Зауважте, що мої тестові випадки в попередньому коментарі базуються на транслітераціях у питанні!)
Тім Педерік,

Далі ㄱ, ㄷ, ㅈйдуть спеціальні випадки (вони стають прагнеми до ㅋ, ㅌ, ㅈ(k, t, j)), також слід виділити ці.
JungHwan Min

Відповіді:


8

Python 3.6, 400 394 байт

Редагувати: Завдяки RootTwo за -6 байт.

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

import re,unicodedata as u
t='-'.join(u.name(i)[16:]for i in input()).lower()
for i in range(19):t=re.sub('h-[gdb]|(?<!n)([gdbsjc]+)(?!\\1)(?!-?[aeiouyw]) gg dd bb -- - h(?=[nmrcktp])|hh hj l(?=[aeiouyw]) l[nr] [nt][nr] tm pm [pm][nr] km kn|kr|ngr c yi weo'.split()[i],([lambda m:'ktpttt'['gdbsjc'.index(m[0][-1])]]+'kk,tt,pp, ,,t,c,r,ll,nn,nm,mm,mn,ngm,ngn,ch,ui,wo'.split(","))[i],t)
print(t)

Як це працює

Рішення намагається використати той факт (про який я дізнався з оригінальної проблеми японської романізації) про те, що романізовані імена символів доступні через модуль unicodedata Python. Для корейської мови вони мають форму HANGUL SYLLABLE <NAME>. На жаль, обробка цих імен, щоб відповідати наданій специфікації та охопити всі сценарії комбінації складів, все ще вимагає трохи зусиль (і байтів).

Перераховують отримані символьні імена все приголосні в своїй дзвінкою формі ніде в складі, наприклад , GGAGGдля , R/Lтранскрибируются як задумано (починаючи R, закінчення L), і CHдається як C(це на самому справі економить нам трохи головного болю).

Перш за все, ми знімаємо HANGUL SYLLABLEчастину (перші 16 знаків), позначаємо межі складу -, а потім застосовуємо ряд RegEx'es для перетворення.

Перший RegEx виглядає особливо неприємно. В основному це перетворення початкових приголосних у їхні закінчувальні еквіваленти (також видалення зайвої літери у разі подвійних приголосних), коли за ними не йде голосна, або для деяких букв - коли їм передують h. (?<!n)Назад ' запобігає відповідності , gякий є частиною ng, і (?!\\1)щодо подальшого гарантує , що ми не конвертувати, наприклад, ssaдо tsa.

Наступні кілька RegEx'е перетворюють початкові подвійні приголосні в їхні незвучні еквіваленти. Ось де -корисні роздільники, оскільки вони допомагають розпізнати граничні зіткнення ( g-g) від подвійних приголосних ( gg). Тепер їх також можна видалити.

Далі ми обробляємо решти h+consonantкомбінацій l->rперед голосними та іншими особливими відмінками.

Нарешті, ми відновлюємо cдо ch, і вирішити деякі інші особливості наших вхідних імен напівкоксу, наприклад, yiзамість того , щоб uiі weoзамість wo.

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


Ласкаво просимо до PPCG! Чудова перша відповідь.
FantaC

1
Гарна відповідь. Як і для python 3.6, m[0]те саме, що m.group(0); економія 6 байт.
RootTwo

5

JavaScript (ES6), 480 байт (WIP)

Це рання спроба, заснована на поточних специфікаціях, щоб отримати кульку. Може знадобитися певне виправлення при вирішенні питань у коментарях.

s=>[...s].map(c=>c<'!'?c:(u=c.charCodeAt()-44032,y='1478ghjlmnpr'.search((p=t).toString(36)),t=u%28,u=u/28|0,v=u%21,x=[2,5,6,11,18].indexOf(u=u/21|0),~x&~y&&(z=parseInt(V[y+68][x],36))>10?V[z+69]:V[p+40]+V[u+21])+V[v],t=0,V='8a6y8ye6e46ye4y64w8wa6o6y4u/w4w6wi/yu/eu/ui/i/g/k21d/t7r/3b/p0s/ss95j5ch/270h922/197l999930/77ng/77270h/bbcd6afaa8gghi5ffak8alaa8llmn4gghp8abaa8gghq5gghr5ggha5gghs8ng1ng3g/2ll/n1n3d/7r/m1m3b/0s/5ch/h'.replace(/\d/g,n=>'pnkmojeta/'[n]+'/').split`/`).join``

Тестові справи

Як?

Після декомпресії масив V містить такі дані:

00-20 vowels
a/ae/ya/yee/eo/e/yeo/ye/o/wa/wae/oe/yo/u/wo/we/wi/yu/eu/ui/i

21-39 starting consonants
g/kk/n/d/tt/r/m/b/pp/s/ss//j/jj/ch/k/t/p/h

40-67 ending consonants
/k/k//n///t/l////////m/p//t/t/ng/t/t/k/t/p/h

68-79 indices of substitution patterns for consecutive consonants
      ('a' = no substitution, 'b' = pattern #0, 'c' = pattern #1, etc.)
bbcde/afaaa/gghij/ffaka/alaaa/llmno/gghpa/abaaa/gghqj/gghrj/gghaj/gghsa

80-97 substitution patterns
ngn/ngm/g/k/ll/nn/nm/d/t/r/mn/mm/b/p/s/j/ch/h

Ми розділяємо кожен символ Хангула на початковий приголосний, голосний і закінчуючий приголосний. До результату додаємо:

  • V[80 + substitution] + V[vowel] якщо є заміна
  • V[40 + previousEndingConsonant] + V[21 + startingConsonant] + V[vowel] інакше

Не '!'може бути 33?
Джонатан Фрех

@JonathanFrech c- не байт. Це 1-символьний рядок. Це було сказано , що при застосуванні арифметичної операції пробіл примушується, 0а інші нецифрові символи примушуються до NaN. Що означає, що c<1насправді слід діяти так, як очікувалося. (І c<33також буде працювати для нецифрових символів, хоча це є випадковим випадком.)
Арнольд,

Додаток @JonathanFrech: c<1також було б правдоподібним "0"(що, мабуть, нормально, якщо введення гарантовано не містить арабської цифри.)
Арнольд,

Дякую. Я не думав, що JavaScript матиме символи, реалізовані як єдиний байт, хоча все-таки спробував. Однак, здавалося, це працює. Радий тепер знати, чому.
Джонатан Фрех

2

Tcl, 529 байт

fconfigure stdin -en utf-8
foreach c [split [read stdin] {}] {scan $c %c n
if {$n < 256} {append s $c} {incr n -44032
append s [string index gKndTrmbPsS-jJCktph [expr $n/588]][lindex {a ae ya yae eo e yeo ye o wa wae oe yo u wo we wi yu eu ui i} [expr $n%588/28]][string index -Ak-n--tl-------mp-BGQDEkFph [expr $n%28]]}}
puts [string map {nr nn
A- g An ngn Ar ngn Am ngm A kk
t- d p- b B- s D- j
nr ll l- r ln ll lr ll
A k B t G t D t E t F t
K kk T tt P pp S ss J jj C ch Q ng
- ""} [regsub -all -- {[tpBDEFh]([nrm])} $s n\\1]]

Алгоритм

  1. Розкладання на показники свинцю, голосних та хвостів
  2. Перший пошук на проміжне алфавітне подання
  3. Застосуйте початковий пропуск для всіх перетворень xn → nn / xm → nm
  4. Застосуйте остаточний пропуск для решти перетворень

Цей алгоритм розкривається для цілей виклику; компромісом є те, що вхід передбачається, що він не містить ні латинських символів, ні символів поза блоком U + AC00 Hangul, як описано в виклику. Це був справжній код, я б утримував усі перетворення в Джамо до остаточного проходу.

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

Тестування

Переконайтеся, що ви можете подати вхід UTF-8 в інтерпретатор Tcl. Це найпростіше зробити за допомогою простого текстового файлу UTF-8. На жаль, Tcl все ще не за замовчуванням UTF-8; це коштувало мені 33 байтів.

Ось мій (зараз жалюгідний) тестовий файл:

한
안녕하세요
나랏말싸미 듕귁에달아

Примітки

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

І з цього приводу корисна якась додаткова інформація. Зокрема, не існує відповідності 1: 1 між привідними та хвостовими приголосними, як здається, пропонується у виклику. Наступні два сайти допомогли вирішити це:
Вікіпедія: Корейська мова, Хангул
Вікіпедія: Хангул Джамо (блок Unicode)

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