Romanize Korece


13

Evet, temelde bir Romanlaştırıcısın bebeğim , ama daha zor . gibi yolu zor.

Korece öğrenmek ZORDUR. en azından Asya dışındaki bir kişi için. Ama en azından öğrenme şansları var, değil mi?

Ne yapmalısın

Size bir Kore Bildirisi verilecektir. Örneğin 안녕하세요,. Girişi Roman telaffuzuna dönüştürmelisiniz. Verilen örnek için çıktı olabilir annyeonghaseyo.

Şimdi teknik oluyor

Korece bir karakterin Başlangıç ​​ünsüz, Ünlü ve Bitiş ünsüz olmak üzere üç bölümü vardır. Bitiş ünsüzü karakterde olmayabilir.

Örneğin, bir (Başlangıç sessiz) ve (Ünlü) ve bir (ünsüz Başlangıç) (Sesli) ve (ünsüz bitiş).

Evert ünsüz ve sesli harfin telaffuzu vardır. Her ünsüzün telaffuzu aşağıdaki gibidir.

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

(- telaffuz veya kullanılmadığı anlamına gelir. bunları işlemeniz gerekmez.)

ve her sesli harf için Telaffuz aşağıdaki gibidir.

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

Şimdi bu gerçek zor kısmı

Ünsüzün telaffuzu daha önce Bitiş ünsüzüne göre değişir. Every Starting / Ending consonant için telaffuz aşağıdaki görüntüdeki gibidir. Teşekkürler, Wikipedia.  Bu olmasaydı, tüm bunları YAZMALIDIR. (Telaffuzlar arasında tire işareti kullanmak zorunda değilsiniz. Gereksiz. Bir hücrenin iki veya daha fazla telaffuzu varsa, birini seçin. Hiç bitmeyen ünsüz yoksa orijinal telaffuzu kullanın.)

Örnekler

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

Örnek öneri memnuniyetle karşılandı. Burada kendi girdileriniz için cevaplar alabilirsiniz . ("Genel metin" te, Revize istediğim şey)


Giriş her zaman Unicode AC00-D7AF + karakterlerinden oluşacak mı?
Arnauld

1
Sarı ile vurgulanmayan birkaç özel ㅎ + X kombinasyonu vardır (örn. ㅎ + ㅈ = ch). Bu, onları desteklememiz gerekmediği anlamına mı geliyor? (Ayrıca, ㅎ resimdeki h yerine t olarak 'romanize edilir' , bu biraz kafa karıştırıcıdır.)
Arnauld

1
Test senaryoları : gist.github.com/perey/563282f8d62c2292d11aabcde0b94d2d @Arnauld'un dediği gibi, özel kombinasyonlarda bazı tuhaflıklar var; vurgulanmış olsun olmasın, tabloda bulduğum tüm testler var. Birden çok seçeneğin olduğu yerde, boşluklarla ayrılırlar. İnsanların onları dışarı atmasını beklediğim için tire kullanılmaz.
Tim Pederick

1
Önerilen çıkış denetimi bağlantınızda "Genel metin" i görmüyorum; "Genel şeyler" mi demek istediniz? Eğer öyleyse, üçünden hangisini kullanmalıyız (Revize, McCune, Yale)? Hiçbiri masanıza uymuyor gibi görünüyor; örneğin, ㅈ ve ardından ㄹ size göre "nn" olmalıdır, ancak bu bağlantıda "tr" veya "cl" olur. (Önceki
yorumdaki

bunu ㄱ, ㄷ, ㅈda özel durumlar ( ㅋ, ㅌ, ㅈ(k, t, j) 'ye çekilir) bunları da vurgulamalıdır.
JungHwan Min

Yanıtlar:


9

Python 3.6, 400 394 bayt

Düzenleme: -6 bayt için RootTwo sayesinde .

Bu benim CodeGolf ile ilgili ilk sunumum, bu yüzden golf oynamak için daha iyi yollar olduğundan eminim, ama henüz kimse ana fikirden bahsetmediği için hala yayınlayacağımı düşündüm ve bu hala diğer çözümlerden önemli ölçüde daha kısa .

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)

Nasıl çalışır

Çözüm, romantize karakter adlarının Python un unicodedata modülü aracılığıyla erişilebilir olduğu gerçeğini (orijinal Japon romanizasyon mücadelesinden öğrendiğim) sömürmeye çalışıyor. Kore dili için HANGUL SYLLABLE <NAME>. Ne yazık ki, bu adları sağlanan spesifikasyonu karşılamak ve tüm hece kombinasyon senaryolarını kapsamak için işlemek yine de biraz çaba gerektirir (ve bayt).

Elde edilen karakter isimleri hece kendi sesli formu her yerde, örneğin tüm sessizler listelemek GGAGGiçin , R/L(başlangıç amaçlandığı gibi transkripsiyonu Rbiten L) ve CHolarak verilir C(bu aslında bize baş ağrısı biraz kaydeder).

Her şeyden önce, HANGUL SYLLABLEparçayı -çıkarırız (ilk 16 karakter), hece sınırlarını işaretleriz ve daha sonra dönüşümleri yapmak için bir dizi RegEx'i uygularız.

İlk RegEx özellikle kötü görünüyor. Temel olarak yaptığı şey, başlangıç ​​ünsüzlerinin bitiş eşdeğerlerine (çift ünsüzler durumunda ekstra mektubu çıkarmak), bir sesli harfle takip edilmedikleri zaman veya bazı harfler için - onlardan önce geldiklerinde dönüştürülmesidir h. (?<!n)Geriye dönük önler eşleştirme gparçasıdır ngve (?!\\1)biz, örneğin dönüştürmediğiniz ileri yönlü olmasını sağlar ssaiçin tsa.

Sonraki birkaç RegEx, başlangıç ​​çift ünsüzlerini sessiz eşdeğerlerine dönüştürüyor. -Ayırıcıların ( g-g) çift çarpışmalardan ( ) ayırt edilmesine yardımcı oldukları için ayırıcıların da işe yaradığı yer burasıdır gg. Şimdi bunlar da çıkarılabilir.

Ardından, sesli harflerden önce ve diğer özel durumlarda kalan h+consonantkombinasyonları ele alıyoruz l->r.

Son olarak, biz geri ciçin ch, ve bu şekilde bizim Gelen karakter isimleri diğer bazı özgünlüklerini, çözmek yiyerine uive weoyerine wo.

Korece bir uzman değilim ve daha fazla yorum yapamam, ancak bu görevde ve Github'da yayınlanan tüm testleri geçiyor gibi görünüyor. Açıkça, eğer çıktı büyük harfle kabul edilebilirse, isim fonksiyonundan aldığımız şey olduğu için birkaç bayt daha tıraş edilebilir.


PPCG'ye Hoşgeldiniz! Harika ilk cevap.
FantaC

1
Güzel cevap. Python 3.6'dan m[0]itibaren m.group(0); 6 bayt tasarrufu.
RootTwo

5

JavaScript (ES6), 480 bayt (WIP)

Bu, topu yuvarlamak için mevcut spesifikasyonlara dayanan erken bir girişimdir. Yorumlardaki sorular ele alındığında bazı düzeltmeler yapılması gerekebilir.

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``

Test senaryoları

Nasıl?

Sıkıştırıldıktan sonra, V dizisi aşağıdaki verileri içerir:

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

Her Hangul karakterini başlangıç ​​ünsüz, ünlü ve bitiş ünsüzüne böldük. Sonuca ekliyoruz:

  • V[80 + substitution] + V[vowel] bir yedek varsa
  • V[40 + previousEndingConsonant] + V[21 + startingConsonant] + V[vowel] aksi takdirde

Can '!'olmaz 33?
Jonathan Frech

@JonathanFrech cbir bayt değildir. 1 karakterlik bir dize. Bununla birlikte , aritmetik bir işlem uygulanırken, boşluk kullanılmaya zorlanırken 0, diğer sayısal olmayan karakterler de zorlanır NaN. Bu c<1, aslında beklendiği gibi çalışması gerektiği anlamına gelir . (Ve c<33bu biraz tesadüfi olmasına rağmen, rakam olmayan karakterler için de işe yarayacaktır.)
Arnauld

c<1@JonathanFrech Eki: için de doğrudur "0"(girişin herhangi bir Arap rakamı içermemesi garanti edilirse muhtemelen tamamdır.)
Arnauld

Teşekkürler. Bununla birlikte, JavaScript'in yine de denenmiş olsa da, karakterlerin tek bir bayt olarak uygulanacağını düşünmedim. Ancak, işe yaramış gibi görünüyordu. Nedenini bilmekten memnunum.
Jonathan Frech

2

Tcl, 529 bayt

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]]

Algoritma

  1. Kurşun, sesli harf ve kuyruk indekslerine ayrışma
  2. İlk ara alfabetik gösterim araması
  3. Tüm xn → nn / xm → nm dönüşümleri için bir ilk geçiş uygulayın
  4. Geri kalan dönüşümler için son bir geçiş uygulayın

Bu algoritma meydan okuma amacıyla gıcırdadı; ticaret-off giriş farz olması durumu değil herhangi Latince alfabetik karakterler içeren, ne de meydan açıklandığı gibi, U + AC00 Hangul bloğu dışındaki karakterler kullanmak. Bu gerçek kod olsaydı, son geçişe kadar tüm dönüşümleri Jamo'da tutardım.

Sanırım bu ünlüleri ve arama tablosundaki tekrarları biraz daha fazla beyin gücü fırlatabilirim, ama bu bugün benden aldığı kadar iyi.

Test yapmak

Tcl yorumlayıcısına UTF-8 girişi sağlayabildiğinizden emin olun. Bu en basit şekilde basit bir UTF-8 metin dosyası ile gerçekleştirilir. Ne yazık ki, Tcl hala varsayılan olarak UTF-8'e varsayılan değildir; bu bana 33 bayta mal oldu.

İşte (şu anda acıklı) test dosyam:

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

notlar

Kore dili hakkında hiçbir şey bilmiyorum (burada az öğrendiğim hariç). Bu, ilk özelliktir ve soru belirtimindeki güncellemeler nedeniyle olası bir düzeltmeyi beklemektedir.

Ve bu konuda, bazı ek bilgiler yararlıdır. Özellikle, kurşun ve kuyruk ünsüzleri arasında meydan okumada önerildiği gibi 1: 1 yazışma yoktur. Aşağıdaki iki site bunu anlamamıza yardımcı oldu:
Wikipedia: Kore dili, Hangul
Wikipedia: Hangul Jamo (Unicode block)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.