로마자 한국어


12

예, 그것은 기본적으로의 당신은 Romanizer, 아기 야 ,하지만 열심히 . 같은 방법으로 열심히.

한국어를 배우는 것은 어렵다. 적어도 아시아 이외의 사람에게는. 그러나 그들은 적어도 배울 기회가 있습니다.

해야 할 일

당신은 한국어 진술을 받게 될 것입니다. 예를 들면 다음과 같습니다 안녕하세요. 입력을 로마 발음으로 변환해야합니다. 주어진 예에서 출력은입니다 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

이제 진짜 어려운 부분

자음의 발음은 엔딩 자음에 의해 이전에 변경됩니다. 모든 시작 / 종료 자음에 대한 발음은 다음 이미지와 같습니다. Wikipedia 감사합니다.  이것이 없다면,이 모든 것을 써야 할 것입니다. (발음 사이에 하이픈을 사용할 필요는 없습니다. 불필요합니다. 셀에 둘 이상의 발음이있는 경우 하나를 선택하십시오. 끝 자음이 없으면 원래 발음을 사용하십시오.)

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

제안 예는 환영했다. 여기에서 자신의 입력에 대한 답변을 얻을 수 있습니다 . ( "일반 텍스트"에있는 하나는 내가 요구하는 것입니다)


입력은 항상 유니 코드 문자 AC00-D7AF + 공백으로 구성됩니까?
Arnauld

1
노란색으로 강조 표시되지 않은 몇 가지 특수 ㅎ + X 조합이 있습니다 (예 : ㅎ + ㅈ = ch). 그것은 우리가 그들을지지 할 필요가 없다는 것을 의미합니까? (또한, ㅎ 같이 '로마자' t 대신 H 비트 혼동되는 사진이다.)
Arnauld

1
테스트 사례 : gist.github.com/perey/563282f8d62c2292d11aabcde0b94d2d @Arnauld가 말했듯이 특수 조합에는 몇 가지 이상한 점이 있습니다. 여기에는 강조 표시 여부에 관계없이 표에서 찾은 모든 항목에 대한 테스트가 있습니다. 여러 옵션이 존재하면 공백으로 구분됩니다. 사람들이 골프를 칠 것으로 예상하기 때문에 하이픈은 사용되지 않습니다.
Tim Pederick

1
제안 된 출력 확인 링크에 "일반 텍스트"가 표시되지 않습니다. "일반적인 것"을 의미합니까? 그렇다면, 우리 중 어느 것을 사용해야합니까 (Revised, McCune, Yale)? 아무도 당신의 테이블과 일치하지 않는 것 같습니다. 예를 들어, ㅈ 뒤에 ㄹ이 오면 "nn"이어야하지만 해당 링크에서 "tr"또는 "cl"입니다. (이전 의견의 테스트 사례는 질문의 음역을 기반으로합니다!)
Tim Pederick

다음 ㄱ, ㄷ, ㅈ또한 특별한 경우 (그들은에 흡입 될 ㅋ, ㅌ, ㅈ너무 사람들을 강조한다 (K, T, J)).
JungHwan Min

답변:


8

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

작동 원리

이 솔루션은 파이썬의 유니 코드 데이터 모듈을 통해 로마자 문자 이름에 액세스 할 수 있다는 사실 (원래 일본어 로마자 도전 과제에서 배운)을 활용하려고합니다. 한국어의 경우 형태는 HANGUL SYLLABLE <NAME>. 안타깝게도 제공된 사양을 충족하고 모든 음절 조합 시나리오를 다루기 위해 이러한 이름을 처리하려면 상당한 노력과 노력이 필요합니다.

얻어진 캐릭터 이름은 음절에있는 그들의 소리 난 형태의 어느 곳, 예를 들어, 모든 자음 나열 GGAGG를 들어 , R/L(시작 의도 한대로 전사되어 R종료 L)과 CH같이 주어진다 C(이 실제로 우리에게 두통의 비트를 저장).

먼저, HANGUL SYLLABLE부분 (처음 16 자)을 제거하고 음절 경계를로 표시 -한 다음 일련의 RegEx를 적용하여 변환을 수행합니다.

첫 번째 RegEx는 특히 불쾌 해 보입니다. 기본적으로 수행하는 것은 시작 자음을 끝 동등 물로 변환하는 것입니다 (더블 자음의 경우 여분의 문자를 제거함) h. (?<!n)lookbehind의 방지 매칭 g의 일부입니다 ng, 그리고 (?!\\1)우리는, 예를 들어, 변환하지 않는 내다 보장하지만 ssatsa.

다음 몇 개의 RegEx는 더블 자음을 시작하여 무성음으로 변환합니다. 여기서는 -분리자가 g-g이중 자음 ( gg) 에서 경계 충돌 ( )을 식별하는 데 도움이되므로 편리합니다 . 이제 제거 할 수도 있습니다.

다음으로 모음 앞 의 나머지 h+consonant조합 l->r및 기타 특수한 경우를 처리합니다.

마지막으로, 우리는 복원 cch, 및 우리의 수신 문자 이름의 다른 pecularities 해결 yi대신 uiweo대신을 wo.

나는 한국어 전문가가 아니며 더 많은 의견을 말할 수 없지만 이것은 작업과 Github에 게시 된 모든 테스트를 통과 한 것으로 보입니다. 분명히 출력이 대문자로 받아 들여지면 이름 함수에서 얻는 것이므로 몇 바이트를 더 줄일 수 있습니다.


PPCG에 오신 것을 환영합니다! 좋은 첫 번째 대답.
FantaC

1
좋은 대답입니다. 파이썬 3.6으로 m[0]동일하다 m.group(0); 6 바이트 절약
RootTwo

5

자바 스크립트 (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없습니까?
Jonathan Frech

@JonathanFrech c는 바이트가 아닙니다. 1 문자열입니다. , 산술 연산을 적용 할 때 공백이 강요 0되고 다른 숫자가 아닌 문자는 강요됩니다 NaN. 어떤 수단 c<1예상대로 실제로 일을해야한다. ( c<33이것은 우연한 일이지만 숫자가 아닌 문자에도 적용됩니다.)
Arnauld

c<1@JonathanFrech Addendum : 또한 진실 할 것입니다 "0"(입력에 아라비아 숫자가 포함되어 있지 않다면 아마도 괜찮을 것입니다)
Arnauld

감사. 그럼에도 불구하고 JavaScript는 문자를 단일 바이트로 구현한다고 생각하지는 않았습니다. 그러나 작동하는 것 같습니다. 이유를 알게되어 기쁘다.
Jonathan Frech

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 대응이 없습니다. 다음 두 사이트는이를 파악하는 데 크게 도움이되었습니다.
Wikipedia : 한국어, 한글
Wikipedia : 한글 자모 (유니 코드 블록)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.