罗马化韩文


12

是的,基本上,您是一个浪漫主义者,宝贝,但是要难一些。象,更难。

学习韩语很困难。至少对于亚洲以外的人来说。但是他们至少有机会学习,对吗?

你必须做什么

您将获得韩国声明。例如,안녕하세요。您必须将输入转换为其罗马发音。对于给定的示例,输出可以为annyeonghaseyo

现在获得技术

朝鲜语字符分为三个部分:起始辅音,元音和结束辅音。字符中可能不存在结尾辅音。

例如,(开始辅音)和(Vowel),并且(开始辅音),(Vowel)和(结束辅音)。

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

现在是真正困难的部分

辅音的发音由之前的结尾辅音改变。每个开始/结束辅音的发音如下图。谢谢,维基百科。 如果没有这个,我必须写所有这一切。 (您不必在发音之间做连字符。这是不必要的。如果一个单元有两个或多个发音,请选择一个。如果没有结尾辅音,请使用原始发音。)

例子

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

示例建议表示欢迎。您可以在此处获得自己输入的答案。(我要的是“一般文本”中的内容,已修订)


输入是否始终由Unicode字符AC00-D7AF +空格组成?
Arnauld

1
有几种特殊的ㅎ+ X组合没有用黄色突出显示(例如ㅎ+ㅈ= ch)。这是否意味着我们不必支持他们?(此外,ㅎ 在图片中用'ro'表示为t而不是h,这有点令人困惑。)
Arnauld

1
测试用例:gist.github.com/perey/563282f8d62c2292d11aabcde0b94d2d正如@Arnauld所说的,特殊组合中有些奇怪之处。它可以测试我在表中找到的所有内容,无论是否突出显示。存在多个选项时,它们之间用空格分隔。我不希望使用连字号,因为我希望人们能打出连字号。
蒂姆·派德里克

1
在您建议的输出检查链接中没有看到“常规文本”;你是说“一般事物”吗?如果是这样,我们应该使用三个中的哪一个(修订版,McCune,耶鲁大学)?似乎没有人适合您的餐桌;例如,根据您的说法,ㅈ后跟ㄹ应该是“ nn”,但在该链接上是“ tr”或“ cl”。(请注意,我之前的评论中的测试案例是基于问题中的音译!)
Tim Pederick

其次ㄱ, ㄷ, ㅈ是特殊情况(它们被吸引到ㅋ, ㅌ, ㅈ(k,t,j))也应突出显示这些情况。
JungHwan Min

Answers:


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>。不幸的是,处理这些名称以满足所提供的规范并覆盖所有音节组合方案仍然需要大量的精力(和字节)。

所获得的角色名称列表中的音节的语音形式的任何地方,例如,所有的辅音GGAGGR/L按预期(起始转录R,结束L),并CH给出C(这实际上为我们节省了一点头痛)。

首先,我们剥离HANGUL SYLLABLE部分(前16个字符),用标记音节边界-,然后应用一系列RegEx进行转换。

第一个RegEx看起来特别讨厌。它的基本作用是将起始辅音转换成它们的末尾等效词(如果是双辅音,则也删除多余的字母),当它们后面没有元音时,或者对于某些字母,在它们之前加上h。后(?<!n)向搜索可防止g成为的一部分进行匹配ng,并且(?!\\1)前瞻确保我们不会将转换ssatsa

接下来的几个RegEx将起始的双辅音转换成它们的清音等效音。在这里,-分隔符也很方便,因为它们有助于区分g-g双辅音(gg)与边界碰撞()。现在也可以将其删除。

接下来,我们处理元音和其他特殊情况之前的其余h+consonant组合l->r

最后,我们还原cch,并解决传入字符名称的其他一些问题,例如yi代替uiweo代替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 Hangul块之外的字符。如果是真正的代码,我会将所有转换保留在Jamo中,直到最后通过为止。

我想我可以在查找表中的那些元音和一些重复上投入更多的才智,但这和我今天得到的一样好。

测试中

确保您可以向Tcl解释器提供UTF-8输入。使用简单的UTF-8文本文件最容易完成此操作。las,默认情况下,Tcl仍不默认为UTF-8;这花了我33个字节。

这是我的(当前可悲的)测试文件:

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

笔记

我对朝鲜语一无所知(除了我在这里学到的知识以外)。这是首次尝试,由于问题规范中的更新而有待修订。

并且,关于此,一些其他信息是有用的。尤其是,挑战中似乎暗示了前导辅音和尾辅音之间没有1:1的对应关系。以下两个站点极大地解决了这一问题:
维基百科:韩文,韩文
维基百科:韩文Jamo(Unicode块)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.