韓国語をローマ字化する


12

はい、それは基本的にあなたはロマナイザー、ベイビーですが、より難しいです。以下のように、難しいです。

韓国語を学ぶのは難しいです。少なくともアジア以外の人にとっては。しかし、彼らには少なくとも学ぶ機会がありますよね?

あなたがしなければならないこと

韓国語の声明が送られます。たとえば、안녕하세요。入力をローマ字の発音に変換する必要があります。与えられた例では、出力はになりますannyeonghaseyo

今では技術的になります

韓国語の文字には、開始子音、母音、および終了子音の3つの部分があります。エンディング子音はキャラクターに存在しない場合があります。

例えば、ある(子音の開始)および(母音)とされている(子音の開始)、 (母音)、及び(子音を終了)。

Evert子音と母音には発音があります。各子音の発音は次のとおりです。

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

今、本当に難しい部分

子音の発音は、前の語尾子音によって変わります。すべての開始/終了子音の発音は、次の図のようになります。ウィキペディア、ありがとうございます。 これがなかったら、私はこれをすべて書かなければなりません。 (発音の間にハイフンを挿入する必要はありません。不要です。セルに2つ以上の発音がある場合は、1つを選択します。末尾の子音がない場合は、元の発音を使用します。)

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

提案例を歓迎します。ここで自分の入力に対する答えを得ることができます。(「一般テキスト」の1つ、改訂版は私が求めているものです)


入力は常にUnicode文字AC00-D7AF +スペースで構成されますか?
アーナウルド

1
黄色で強調表示されていない特別なㅎ+ Xの組み合わせがいくつかあります(例ㅎ+ㅈ= ch)。それは、彼らをサポートする必要がないということですか?(また、ㅎは写真ではhの代わりにtとして「ローマ字化」されており、少々紛らわしいです。)
アーナルド

1
テストケース:gist.github.com/perey/563282f8d62c2292d11aabcde0b94d2d @Arnauldが言うように、特別な組み合わせにはいくつかの奇妙な点があります。これには、強調表示されているかどうかに関係なく、テーブルで見つかったすべてのテストがあります。複数のオプションが存在する場合、それらはスペースで区切られます。ハイフンは使われません。人々がゴルフをすることを期待しているからです。
ティムペデリック

1
推奨される出力チェックリンクに「一般テキスト」が表示されません。「一般的なもの」という意味ですか?その場合、3つのうちどれを使用する必要がありますか(改訂、マッキューン、エール)?テーブルに一致するものはないようです。たとえば、ㅈに続いては「nn」である必要がありますが、そのリンクでは「tr」または「cl」です。(前のコメントの私のテストケースは、質問の音訳に基づいていることに注意してください!)
ティムペデリック

続いㄱ, ㄷ, ㅈも特別な場合(それらが吸引なっていることはㅋ, ㅌ, ㅈ(K、T、J))あまりにもそれらを強調すべきです。
ジョンファンミン

回答:


8

パイソン3.6、400の 394バイト

編集: -6バイトのRootTwoに感謝します。

これは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)

使い方

このソリューションは、ローマ字化された文字名がPythonのunicodedataモジュールを介してアクセス可能であるという事実(最初の日本語のローマ字化の課題から学んだこと)を悪用しようとします。韓国語の場合、彼らはHANGUL SYLLABLE <NAME>ます。残念ながら、指定された仕様を満たし、すべての音節の組み合わせシナリオをカバーするためにこれらの名前を処理するには、依然としてかなりの労力(およびバイト)が必要です。

得られた文字名は音節での有声音フォームの任意の場所ですべての子音を一覧表示する、などGGAGGのためにR/L意図したとおり(開始転写されR、終了L)、およびCHとして与えられ、C(これは実際に私たちの頭痛のビットを節約できます)。

まず、私たちは HANGUL SYLLABLEパート(最初の16文字)-を取り除き、音節の境界をでマークしてから、一連の正規表現を適用して変換を行います。

最初のRegExは特に厄介に見えます。基本的には、子音の後に母音が続かない場合、またはいくつかの文字の場合、先頭の子音が末尾の同等語に変換されます(二重子音の場合は余分な文字も削除されhます)。(?<!n)後読み防止マッチングgの一部でありng、そして(?!\\1)我々は、例えば、変換しないことを先読み性を保証ssaしますtsa

次のいくつかのRegExは、開始の二重子音を無声の同等語に変換します。のはここだ-、彼らは(境界衝突目の肥え助けるようセパレータも便利になるg-g(二重子音から)gg)。これで削除することもできます。

次に、母音の前の残りのh+consonant組み合わせl->r、およびその他の特殊なケースを処理します。

最後に、に復元cch、の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、これは一種の偶然ですが、数字以外の文字でも機能します。)
Arnauld

@JonathanFrech補遺:c<1真実でもあります"0"(入力にアラビア数字が含まれないことが保証されている場合は、おそらく大丈夫です。)
Arnauld

ありがとう。それにもかかわらず試してみましたが、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ハングルブロック以外の文字を使用します。この実際のコードであれば、最終パスまでJamoのすべての変換を保持します。

これらの母音とルックアップテーブルの繰り返しの一部を処理する際に、さらに頭脳を投じることができると思いますが、これは今日の私から得られるものと同じくらい良いことです。

テスト中

TclインタープリターにUTF-8入力を提供できることを確認してください。これは、単純なUTF-8テキストファイルで最も簡単に実現できます。残念ながら、Tclは依然としてデフォルトでUTF-8にデフォルト設定されていません。これには33バイトかかりました。

これが私の(現在は哀れな)テストファイルです。

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

ノート

韓国語については何も知りません(ここで学んだことを少しだけ除いて)。これは最初の試みであり、質問仕様の更新による潜在的な改訂待ちです。

そして、それについては、いくつかの追加情報が役立ちます。特に、課題で示唆されているように、リード子音とテール子音の間に1対1の対応はありません。次の2つのサイトは、それを非常に理解するのに役立ちました。
ウィキペディア:韓国語、ハングル
ウィキペディア:ハングルジャモ(Unicodeブロック)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.