Romanizzare il coreano


12

Sì, fondamentalmente sei un romanizer, baby , ma più difficile . tipo, molto più difficile.

Imparare il coreano è DIFFICILE. almeno per una persona fuori dall'Asia. Ma almeno hanno la possibilità di imparare, giusto?

Cosa devi fare

Ti verrà data una dichiarazione coreana. Ad esempio 안녕하세요,. È necessario convertire l'input nella sua pronuncia romana. Per l'esempio fornito, l'output può essere annyeonghaseyo.

Ora diventa tecnico

Un personaggio coreano ha tre parti, consonante iniziale, vocale e consonante finale. La consonante finale non può esistere nel personaggio.

Ad esempio, è (consonante iniziale) e (vocale), ed è (consonante iniziale), (vocale) e (consonante finale).

La consonante e vocale ribalta ha la sua pronuncia. La pronuncia per ciascuna consonante è la seguente.

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

(- significa nessuna pronuncia o non utilizzato. Non è necessario gestirli.)

e la pronuncia per ciascuna vocale è la seguente.

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

Ora è la vera parte difficile

La pronuncia della consonante cambia prima dalla consonante finale. La pronuncia per ogni consonante iniziale / finale è la seguente immagine. Grazie Wikipedia.  Se non ci fosse, dovrei scrivere tutto questo. (Non è necessario eseguire il trattino tra le pronunce. Non è necessario. Se una cella ha due o più pronunce, scegline una. Se non c'è consonante finale, usa la pronuncia originale.)

Esempi

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

Esempio suggerito accolto. Puoi ottenere risposte per i tuoi input qui . (Quello in "Testo generale", Revised è quello che sto chiedendo)


L'ingresso sarà sempre composto da caratteri Unicode AC00-D7AF + spazio?
Arnauld,

1
Esistono diverse combinazioni speciali ㅎ + X che non sono evidenziate in giallo (ad es. ㅎ + ㅈ = ch). Ciò significa che non dobbiamo sostenerli? (Inoltre, ㅎ è 'romanizzato' come t invece di h nella figura, il che è un po 'confuso.)
Arnauld

1
Casi di prova: gist.github.com/perey/563282f8d62c2292d11aabcde0b94d2d Come dice @Arnauld, ci sono alcune stranezze nelle combinazioni speciali; questo ha dei test per tutti quelli che ho trovato nella tabella, evidenziati o meno. Laddove esistono più opzioni, sono separate dallo spazio. Non vengono usati trattini poiché mi aspetto che le persone li giochino.
Tim Pederick,

1
Non vedo "Testo generale" nel link di verifica dell'output suggerito; vuoi dire "cose ​​generali"? In tal caso, quale dei tre dovremmo usare (Revised, McCune, Yale)? Nessuno sembra corrispondere al tuo tavolo; per esempio, ㅈ seguito da ㄹ dovrebbe essere "nn" secondo te ma è "tr" o "cl" in quel link. (Nota che i miei casi di test nel commento precedente sono basati sulle traslitterazioni nella domanda!)
Tim Pederick,

seguiti ㄱ, ㄷ, ㅈanche da casi speciali (vengono aspirati a ㅋ, ㅌ, ㅈ(k, t, j)) dovrebbero evidenziare anche quelli.
JungHwan Min

Risposte:


8

Python 3.6, 400 394 byte

Modifica: grazie a RootTwo per -6 byte.

Questa è la mia prima presentazione su CodeGolf, quindi sono abbastanza sicuro che ci siano modi migliori per giocare a golf, ma ho pensato di pubblicarlo ancora, dato che nessuno ha ancora menzionato l'idea chiave, e questo è ancora significativamente più breve di altre soluzioni .

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)

Come funziona

La soluzione tenta di sfruttare il fatto (che ho appreso dalla sfida originale della romanizzazione giapponese) che i nomi dei personaggi romanizzati sono accessibili attraverso il modulo unicodedata di Python. Per la lingua coreana, assumono la forma di HANGUL SYLLABLE <NAME>. Sfortunatamente, l'elaborazione di questi nomi per soddisfare le specifiche fornite e per coprire tutti gli scenari di combinazione di sillabe richiede ancora un po 'di sforzo (e byte).

I nomi dei personaggi ottenuti elencano tutte le consonanti nella loro forma sonora in qualsiasi punto della sillaba, ad esempio GGAGGper , R/Lsono trascritti come previsto (inizio R, fine L), e CHviene dato come C(questo in realtà ci fa risparmiare un po 'di mal di testa).

Prima di tutto, eliminiamo la HANGUL SYLLABLEparte (i primi 16 caratteri), contrassegniamo i confini della sillaba con -e quindi applichiamo una serie di RegEx per eseguire le conversioni.

Il primo RegEx sembra particolarmente brutto. Ciò che fondamentalmente fa, è la conversione delle consonanti iniziali nei loro equivalenti finali (rimuovendo anche la lettera aggiuntiva in caso di doppie consonanti), quando non sono seguite da una vocale, o per alcune lettere - quando sono precedute da h. L' (?<!n)impedisce lookbehind corrispondente gche è parte ng, e (?!\\1)assicura lookahead che non ci convertiamo, ad esempio, ssaa tsa.

I prossimi RegEx convertono le doppie consonanti iniziali in equivalenti non fatturati. Ecco dove -sono utili anche i separatori che aiutano a discernere le collisioni di confine ( g-g) dalle doppie consonanti ( gg). Ora possono anche essere rimossi.

Successivamente, gestiamo le h+consonantcombinazioni rimanenti , l->rprima delle vocali e di altri casi speciali.

Infine, ripristiniamo ca ch, e risolvere alcuni altri peculiarità dei nostri nomi char in arrivo, come yiinvece uie weoal posto di wo.

Non sono un esperto in coreano e non posso commentare molto di più, ma questo sembra superare tutti i test pubblicati nell'attività e su Github. Ovviamente, alcuni byte in più potrebbero essere eliminati, se l'output è accettabile in maiuscolo, poiché questo è ciò che otteniamo dalla funzione name.


Benvenuti in PPCG! Ottima prima risposta.
FantaC,

1
Bella risposta. A partire da Python 3.6, m[0]è lo stesso di m.group(0); risparmio di 6 byte.
Root Due

5

JavaScript (ES6), 480 byte (WIP)

Questo è un tentativo iniziale basato sulle specifiche attuali per far rotolare la palla. Potrebbe essere necessario risolvere alcuni problemi quando vengono poste le domande nei commenti.

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

Casi test

Come?

Una volta decompresso, l'array V contiene i seguenti dati:

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

Dividiamo ogni personaggio di Hangul in consonante iniziale, vocale e consonante finale. Aggiungiamo al risultato:

  • V[80 + substitution] + V[vowel] se c'è una sostituzione
  • V[40 + previousEndingConsonant] + V[21 + startingConsonant] + V[vowel] altrimenti

Non '!'può essere 33?
Jonathan Frech,

@JonathanFrech cnon è un byte. È una stringa di 1 carattere. Detto questo , quando si applica un'operazione aritmetica, viene costretto uno spazio 0mentre vengono costretti altri caratteri non numerici NaN. Ciò significa che c<1dovrebbe effettivamente funzionare come previsto. (E c<33funzionerebbe anche con personaggi non digitati, anche se questo è un po 'fortuito.)
Arnauld

Addendum @JonathanFrech: c<1sarebbe anche vero per "0"(il che è probabilmente OK se l'input è garantito per non contenere alcun numero arabo).
Arnauld

Grazie. Non pensavo che JavaScript avrebbe implementato i caratteri come un singolo byte, anche se comunque provato. Tuttavia, sembrava funzionare. Sono contento di sapere ora perché.
Jonathan Frech,

2

Tcl, 529 byte

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

Algoritmo

  1. Decomposizione in indici di piombo, vocale e coda
  2. Primo sguardo alla rappresentazione alfabetica intermedia
  3. Applicare un passaggio iniziale per tutte le trasformazioni xn → nn / xm → nm
  4. Applica un passaggio finale per le trasformazioni rimanenti

Questo algoritmo è elaborato ai fini della sfida; il compromesso è che si presume che l'input non contenga caratteri alfabetici latini, né l'uso di caratteri al di fuori del blocco Hangul U + AC00 come descritto nella sfida. Se questo codice fosse reale, terrei tutte le trasformazioni in Jamo fino al passaggio finale.

Suppongo che potrei lanciare un po 'più di potere cerebrale a scricchiolare quelle vocali e alcune delle ripetizioni nella tabella di ricerca, ma questo è buono come mi arriva oggi.

analisi

Assicurarsi di poter fornire l'ingresso UTF-8 all'interprete Tcl. Ciò è più facile da realizzare con un semplice file di testo UTF-8. Purtroppo, per impostazione predefinita Tcl non utilizza ancora UTF-8; questo mi è costato 33 byte.

Ecco il mio file di test (attualmente patetico):

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

Appunti

Non so nulla della lingua coreana (tranne quel poco che ho imparato qui). Questo è un primo tentativo, in attesa di una potenziale revisione a causa di aggiornamenti nelle specifiche della domanda.

E, a tale proposito, alcune informazioni aggiuntive sono utili. In particolare, non esiste una corrispondenza 1: 1 tra consonanti di coda e di coda, come sembra suggerito nella sfida. I seguenti due siti hanno aiutato immensamente a capirlo:
Wikipedia: lingua coreana, Hangul
Wikipedia: Hangul Jamo (blocco Unicode)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.