Romaniser le coréen

12

Oui, c'est fondamentalement tu es un romaniseur, bébé , mais plus dur . comme, beaucoup plus dur.

Apprendre le coréen est difficile. au moins pour une personne en dehors de l'Asie. Mais ils ont au moins la chance d'apprendre, non?

Ce que vous devez faire

Vous recevrez une déclaration coréenne. Par exemple 안녕하세요,. Vous devez convertir l'entrée en sa prononciation romaine. Pour l'exemple donné, la sortie peut être annyeonghaseyo.

Maintenant ça devient technique

Un caractère coréen comporte trois parties, la consonne de départ, la voyelle et la consonne de fin. La consonne de fin peut ne pas exister dans le caractère.

Par exemple, est (Consonne de départ) et (Voyelle), et est (Consonne de départ), (Voyelle) et (Consonne de fin).

Evert consonne et voyelle a sa prononciation. La prononciation de chaque consonne est la suivante.

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

(- signifie pas de prononciation ou non utilisé. vous n'avez pas à les gérer.)

et la prononciation de chaque voyelles est la suivante.

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

Maintenant c'est la vraie partie difficile

La prononciation de la consonne change par la consonne de fin en avant. La prononciation de chaque consonne de début / fin est la suivante. Merci, Wikipedia.  S'il n'y avait pas cela, je devrais ÉCRIRE tout cela. (Vous n'avez pas besoin de faire le trait d'union entre les prononciations. Ce n'est pas nécessaire. Si une cellule a deux prononciations ou plus, choisissez-en une. S'il n'y a pas de consonne de fin, utilisez la prononciation originale.)

Exemples

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

Exemple de suggestion bienvenu. Vous pouvez obtenir des réponses pour vos propres contributions ici . (Celui du "texte général", révisé est ce que je demande)

Matthew Roh
la source
L'entrée sera-t-elle toujours composée de caractères Unicode AC00-D7AF + espace?
Arnauld
1
Il existe plusieurs combinaisons spéciales ㅎ + X qui ne sont pas surlignées en jaune (par exemple ㅎ + ㅈ = ch). Est-ce à dire que nous n'avons pas à les soutenir? (De plus, ㅎ est 'romanisé' comme t au lieu de h dans l'image, ce qui est un peu déroutant.)
Arnauld
1
Cas de test: gist.github.com/perey/563282f8d62c2292d11aabcde0b94d2d Comme @Arnauld le dit, il y a des bizarreries dans les combinaisons spéciales; cela a des tests pour tous ceux que j'ai trouvés dans le tableau, qu'ils soient en surbrillance ou non. Lorsque plusieurs options existent, elles sont séparées par des espaces. Aucun trait d'union n'est utilisé car j'attends des gens qu'ils jouent au golf.
Tim Pederick
1
Je ne vois pas le "texte général" dans votre lien de vérification de sortie suggéré; voulez-vous dire "des choses générales"? Si oui, lequel des trois devrions-nous utiliser (Revised, McCune, Yale)? Aucun ne semble correspondre à votre table; par exemple, ㅈ suivi de ㄹ devrait être "nn" selon vous mais est "tr" ou "cl" à ce lien. (Notez que mes cas de test dans le commentaire précédent sont basés sur des translittérations dans la question!)
Tim Pederick
suivi ㄱ, ㄷ, ㅈsont également des cas particuliers (ils deviennent aspirés à ㅋ, ㅌ, ㅈ(k, t, j)) devrait mettre en évidence ceux qui sont trop.
JungHwan Min

Réponses:

8

Python 3.6, 400 394 octets

Edit: Merci à RootTwo pour -6 octets.

Ceci est ma première soumission sur CodeGolf, donc je suis presque sûr qu'il existe de meilleures façons de jouer au golf, mais je pensais que je le posterais, car personne n'a encore mentionné l'idée clé, et cela est encore beaucoup plus court que les autres solutions. .

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)

Comment ça fonctionne

La solution tente d'exploiter le fait (que j'ai appris du défi de romanisation japonais d'origine) que les noms de caractères romanisés sont accessibles via le module unicodedata de Python. Pour la langue coréenne, ils prennent la forme de HANGUL SYLLABLE <NAME>. Malheureusement, le traitement de ces noms pour répondre aux spécifications fournies et pour couvrir tous les scénarios de combinaison de syllabes nécessite encore pas mal d'efforts (et d'octets).

Les noms de caractères obtenus répertorient toutes les consonnes sous leur forme vocale n'importe où dans la syllabe, par exemple GGAGGpour , R/Lsont transcrites comme prévu (début R, fin L) et CHsont données comme C(cela nous évite en fait un peu de mal de tête).

Tout d'abord, nous supprimons la HANGUL SYLLABLEpartie (les 16 premiers caractères), marquons les limites des syllabes avec -, puis appliquons une série de RegEx'es pour effectuer les conversions.

Le premier RegEx a l'air particulièrement méchant. Ce qu'il fait essentiellement, c'est la conversion des consonnes de départ en leurs équivalents finaux (en supprimant également la lettre supplémentaire en cas de doubles consonnes), lorsqu'elles ne sont pas suivies d'une voyelle, ou pour certaines lettres - lorsqu'elles sont précédées de h. Le (?<!n)lookbehind empêche la correspondance gqui fait partie de ng, et (?!\\1)lookahead garantit que nous ne convertissons pas, par exemple, ssaen tsa.

Les prochains RegEx'es convertissent les doubles consonnes de départ en leurs équivalents non vocaux. Voici où les -séparateurs sont également utiles car ils aident à discerner les collisions aux limites ( g-g) des consonnes doubles ( gg). Maintenant, ils peuvent également être supprimés.

Ensuite, nous traitons les h+consonantcombinaisons restantes , l->ravant les voyelles, et d'autres cas spéciaux.

Enfin, nous rétablissons cà chet résoudre quelques autres particularités de nos noms char entrants, comme au yilieu de uiet au weolieu de wo.

Je ne suis pas un expert en coréen et je ne peux pas en dire plus, mais cela semble passer tous les tests publiés dans la tâche et sur Github. Évidemment, quelques octets supplémentaires pourraient être supprimés, si la sortie est acceptable en majuscules, car c'est ce que nous obtenons de la fonction de nom.

Kirill L.
la source
Bienvenue chez PPCG! Grande première réponse.
FantaC
1
Bonne réponse. À partir de python 3.6, m[0]est identique à m.group(0); économiser 6 octets.
RootTwo
5

JavaScript (ES6), 480 octets (WIP)

Il s'agit d'une première tentative basée sur les spécifications actuelles pour faire rouler la balle. Cela peut nécessiter une correction lorsque les questions dans les commentaires sont traitées.

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

Cas de test

Comment?

Une fois décompressé, le tableau V contient les données suivantes:

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

Nous divisons chaque caractère Hangul en consonne de départ, voyelle et consonne de fin. On ajoute au résultat:

  • V[80 + substitution] + V[vowel] s'il y a une substitution
  • V[40 + previousEndingConsonant] + V[21 + startingConsonant] + V[vowel] autrement
Arnauld
la source
Ne peut '!'pas l'être 33?
Jonathan Frech
@JonathanFrech cn'est pas un octet. C'est une chaîne de 1 caractère. Cela dit , lors de l'application d'une opération arithmétique, un espace est contraint 0tandis que d'autres caractères non numériques sont contraints NaN. Ce qui signifie que cela c<1devrait réellement fonctionner comme prévu. (Et c<33cela fonctionnerait également pour les caractères non numériques, bien que ce soit un peu fortuit.)
Arnauld
@JonathanFrech Addendum: c<1serait également vrai pour "0"(ce qui est probablement OK si l'entrée est garantie de ne contenir aucun chiffre arabe.)
Arnauld
Merci. Je ne pensais pas que JavaScript aurait des caractères implémentés comme un seul octet, bien qu'essayé néanmoins. Cependant, cela semblait fonctionner. Heureux de savoir maintenant pourquoi.
Jonathan Frech
2

Tcl, 529 octets

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

Algorithme

  1. Décomposition en indices de plomb, de voyelle et de queue
  2. Première recherche de représentation alphabétique intermédiaire
  3. Appliquer une passe initiale pour toutes les transformées xn → nn / xm → nm
  4. Appliquer une dernière passe pour les transformations restantes

Cet algorithme est resserré aux fins du défi; le compromis étant que l'entrée est supposée ne contenir aucun caractère alphabétique latin, ni utiliser des caractères en dehors du bloc Hangul U + AC00 comme décrit dans le défi. Si c'était ce vrai code, je garderais toutes les transformations dans Jamo jusqu'à la passe finale.

Je suppose que je pourrais jeter un peu plus de cervelle à croquer ces voyelles et certaines des répétitions dans la table de recherche, mais c'est aussi bon que ce que je reçois de moi aujourd'hui.

Essai

Assurez-vous que vous pouvez fournir une entrée UTF-8 à l'interpréteur Tcl. Cela est plus facile à réaliser avec un simple fichier texte UTF-8. Hélas, Tcl n'est toujours pas par défaut UTF-8 par défaut; cela m'a coûté 33 octets.

Voici mon fichier de test (actuellement pathétique):

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

Remarques

Je ne connais rien à la langue coréenne (sauf le peu que j'ai appris ici). Il s'agit d'une première tentative, en attendant une éventuelle révision en raison de mises à jour de la spécification de la question.

Et, à ce sujet, quelques informations supplémentaires sont utiles. En particulier, il n'y a pas de correspondance 1: 1 entre les consonnes de tête et de queue, comme semble le suggérer le défi. Les deux sites suivants ont énormément aidé à comprendre cela:
Wikipedia: langue coréenne, Hangul
Wikipedia: Hangul Jamo (bloc Unicode)

Dúthomhas
la source