Conversion entre le clavier coréen à deux ensembles et le clavier qwerty

14

introduction

C'est un peu comme la disposition du clavier DVORAK , mais BEAUCOUP plus difficile.

Parlons d'abord du clavier coréen. Comme vous pouvez le voir sur Wikipedia , il existe une clé Kor / Eng pour basculer entre les jeux de clés coréens et anglais.

Les Coréens tapent parfois mal: ils essaient d'écrire en coréen sur un clavier qwerty ou en anglais sur un clavier à deux jeux.

Donc, voici le problème: si des caractères coréens donnés sont saisis sur un clavier à deux jeux, convertissez-les en caractères alphabétiques tapés sur le clavier qwerty. Si des caractères alphabétiques donnés sont saisis dans qwerty, remplacez-le par un clavier à deux jeux.

Clavier à deux jeux

Voici la disposition du clavier à deux ensembles:

ㅂㅈㄷㄱㅅㅛㅕㅑㅐㅔ
 ㅁㄴㅇㄹㅎㅗㅓㅏㅣ
  ㅋㅌㅊㅍㅠㅜㅡ

et avec la touche shift:

ㅃㅉㄸㄲㅆㅛㅕㅑㅒㅖ

seule la rangée du haut change tandis que les autres ne le font pas.

À propos des caractères coréens

si ça se terminait ici, ça pourrait être facile, mais non. Lorsque vous tapez

dkssud, tprP!

la sortie n'est pas affichée de cette manière:

ㅇㅏㄴㄴㅕㅇ, ㅅㅔㄱㅖ!

mais de cette façon:

안녕, 세계!(means Hello, World!)

et cela rend les choses beaucoup plus difficiles.

Les caractères coréens sont séparés en trois parties: «Choseong (consonne)», «Jungseong (voyelle)» et «Jongseong (consonne à la fin de la syllabe: peut être vide)», et vous devez le séparer.

Heureusement, il existe un moyen de le faire.

Comment se séparer

Il y a 19 Choseong, 21 Jungseong et 28 Jongseong (avec blanc), et 0xAC00 est '가', premier caractère des caractères coréens. En utilisant cela, nous pouvons séparer les caractères coréens en trois parties. Voici l'ordre de chacun et sa position sur un clavier à deux jeux.

ordre choisi:

ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ
r R s e E f a q Q t T d w W c z x v g

ordre jungseong:

ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ
k o i O j p u P h hk ho hl y n nj np nl b m ml l

ordre de jongseong:

()ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ
()r R rt s sw sg e f fr fa fq ft fx fv fg a q qt t T d w c z x v g

Let dire l' (unicode value of some character) - 0xAC00est Korean_code, et l' indice de TCH'ÔSONG, djoungsong, Jongseong est Cho, Jung, Jong.

Alors, Korean_codeest(Cho * 21 * 28) + Jung * 28 + Jong

Voici le code javascript qui sépare le caractère coréen de ce site Web coréen, pour votre commodité.

var rCho = [ "ㄱ", "ㄲ", "ㄴ", "ㄷ", "ㄸ", "ㄹ", "ㅁ", "ㅂ", "ㅃ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅉ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ" ];
var rJung =[ "ㅏ", "ㅐ", "ㅑ", "ㅒ", "ㅓ", "ㅔ", "ㅕ", "ㅖ", "ㅗ", "ㅘ", "ㅙ", "ㅚ", "ㅛ", "ㅜ", "ㅝ", "ㅞ", "ㅟ", "ㅠ", "ㅡ", "ㅢ", "ㅣ" ];
var rJong = [ "", "ㄱ", "ㄲ", "ㄳ", "ㄴ", "ㄵ", "ㄶ", "ㄷ", "ㄹ", "ㄺ", "ㄻ", "ㄼ", "ㄽ", "ㄾ","ㄿ", "ㅀ", "ㅁ", "ㅂ", "ㅄ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ" ];
var cho, jung, jong;
var sTest = "탱";
var nTmp = sTest.charCodeAt(0) - 0xAC00;
jong = nTmp % 28; // Jeongseong
jung = ((nTmp - jong) / 28 ) % 21 // Jungseong
cho = ( ( (nTmp - jong) / 28 ) - jung ) / 21 // Choseong

alert("Choseong:" + rCho[cho] + "\n" + "Jungseong:" + rJung[jung] + "\n" + "Jongseong:" + rJong[jong]);

Une fois assemblé

  1. Notez que , , , , , , est une combinaison d'autres jungseongs.
ㅗ+ㅏ=ㅘ, ㅗ+ㅐ=ㅙ, ㅗ+ㅣ=ㅚ, ㅜ+ㅓ=ㅝ, ㅜ+ㅔ=ㅞ, ㅜ+ㅣ=ㅟ, ㅡ+ㅣ=ㅢ
  1. Choseong est nécessaire. Cela signifie que si frkest donné, ce qui signifie ㄹㄱㅏqu'il peut changer de deux manières: ㄺㅏet ㄹ가. Ensuite, vous devez le convertir d'une manière qui a choisiong. S'ils sont jjjrjrdonnés, c'est-à-dire ㅓㅓㅓㄱㅓㄱ, les principaux n'ont rien qui puisse être choisi, mais le quatrième a qui peut être choisi, alors c'est changé en ㅓㅓㅓ걱.

Un autre exemple: 세계( tprP). Il peut être changé en 섹ㅖ( (ㅅㅔㄱ)(ㅖ)), mais comme chose est nécessaire, il est changé en 세계( (ㅅㅔ)(ㄱㅖ))

Exemples

entrée 1

안녕하세요

sortie 1

dkssudgktpdy

entrée 2

input 2

sortie 2

ㅑㅞㅕㅅ 2

entrée 3

힘ㄴㄴ

sortie 3

glass

entrée 4

아희(Aheui) is esolang which you can program with pure Korean characters.

sortie 4

dkgml(모뎌ㅑ) ㅑㄴ ㄷ내ㅣ뭏 조ㅑ초 ㅛㅐㅕ ㅊ무 ㅔ갷ㄱ므 쟈소 ㅔㅕㄱㄷ ㅏㅐㄱㄷ무 촘ㄱㅁㅊㅅㄷㄱㄴ.

entrée 5

dkssud, tprP!

sortie 5

안녕, 세계!

entrée 6

ㅗ디ㅣㅐ, 째깅! Hello, World!

sortie 6

hello, World! ㅗ디ㅣㅐ, 째깅!

Le code le plus court gagne. (en octets)

Nouvelle règle pour votre commodité

Vous pouvez ignorer des caractères comme ceux Aqui n'ont pas d'équivalent dans un clavier à deux jeux. donc Aheuià Aㅗ뎌ㅑest OK. Mais, si vous passez Aheuià 모뎌ㅑ, vous pouvez obtenir -5 points, vous pouvez donc gagner 5 octets.

Vous pouvez séparer deux jungseongs (comme pour ㅗ+ㅏ). comme rhkà 고ㅏ, ou howà ㅗㅐㅈ. Mais si vous le combinez (comme rhkà ou howà ㅙㅈ), vous pouvez gagner -5 points supplémentaires.

LegenDUST
la source
Dans la section d' ordre jungseong , une des lettres est manquante. Je vois 21 symboles coréens, mais seulement 20 lettres (-paires). EDIT: Semble manquer un procès laprès mlpour le symbole coréen .
Kevin Cruijssen
@KevinCruijssen modifié. l pour ㅣ.
LegenDUST
1
Parfois, il peut y avoir plus d'une interprétation. Par exemple, fjfaupourrait être interprété comme 럶ㅕou 럴며. Comment résolvons-nous cela?
Nick Kennedy
1
@LegenDUST Eh bien, je ne peux pas lire un seul mot coréen, donc je vais devoir aller avec votre explication. ; p Comme tprPdans le cas de test 5: cela se transforme en ㅅㅔㄱㅖ, où est un chose choisie, est une jungseong et est une jongseong. Donc, cela ne devrait-il pas se transformer en 섷ㅖ(groupé comme (ㅅㅔㄱ)(ㅖ)) au lieu de 세계(groupé comme (ㅅㅔ)(ㄱㅖ))? Dans un commentaire précédent, vous déclarez qu'il s'agit d'interpréter en tapant, donc je m'attendrais ㅅㅔㄱà le transformer en . Ou le coréen tape-t-il de droite à gauche au lieu de gauche à droite?
Kevin Cruijssen
1
@KevinCruijssen Fichier PDF d'Unicode.org. AC00 ( ) à D7AF ( ).
LegenDUST

Réponses:

6

Gelée , 296 264 octets

Ẏœṣjƭƒ
“ȮdȥŒ~ṙ7Ṗ:4Ȧịعʂ ="÷Ƥi-ẓdµ£f§ñỌ¥ẋaḣc~Ṡd1ÄḅQ¥_æ>VÑʠ|⁵Ċ³(Ė8ịẋs|Ṇdɼ⁼:Œẓİ,ḃṙɠX’ṃØẠs2ḟ€”A
“|zƒẉ“®6ẎẈ3°Ɠ“⁸)Ƙ¿’ḃ2’T€ị¢
¢ĖẈṪ$ÞṚƊ€
3£OŻ€3¦ŒpFḟ0Ɗ€J+“Ḥœ’,ƲyO2£OJ+⁽.[,Ʋ¤y¹ỌŒḊ?€µ¢ṖŒpZF€’ḋ588,28+“Ḥþ’Ʋ0;,ʋ/ṚƲ€ñṣ0ḊḢ+®Ṫ¤Ɗ;ṫ®$Ɗ¹Ḋ;⁶Ṫ⁼ṁ@¥¥Ƈ@¢ṪẈṪ‘;Ʋ€¤ḢƲ©?€ṭḢƲF2£żJ+⁽.[Ɗ$ẈṪ$ÞṚ¤ñỌ

Essayez-le en ligne!

Un programme complet qui prend une chaîne comme argument et renvoie une chaîne (qui est implicitement imprimée). Cela fonctionne en trois passes: tout d'abord, il convertit tous les caractères coréens en listes de points de code pour les lettres latines. Ensuite, il identifie et construit les caractères coréens composés. Enfin, il transforme toutes les lettres latines errantes restantes en équivalent coréen. Notez que les autres caractères et lettres latines qui n'apparaissent pas dans la spécification (par exemple A) sont laissés seuls.

Si une conversion en minuscules des majuscules en dehors des spécifications est nécessaire, cela peut être fait au coût de 10 octets supplémentaires .

Explication

Lien auxiliaire 1 : lien dyadique avec les arguments x et y. x est une liste de paires de recherche et de remplacement de sous-listes. y aura chaque sous-liste de recherche remplacée par la sous-liste de remplacement correspondante

Ẏ      | Tighten (reduce to a single list of alternating search and replace sublists)
     ƒ | Reduce using y as starting argument and the following link:
    ƭ  | - Alternate between using the following two links:
 œṣ    |   - Split at sublist
   j   |   - Join using sublist

Lien d'assistance 2 : Liste des caractères latins / paires de caractères dans l'ordre qui correspond à l'ordre Unicode des caractères coréens

“Ȯ..X’          | Base 250 integer 912...
      ṃØẠ       | Base decompress into Latin letters (A..Za..z)
         s2     | Split into twos
           ḟ€”A | Filter out A from each (used as filler for the single characters)

Lien Aide 3 : Listes des caractères latins utilisés pour TCH'ÔSONG, djoungsong et Jongseong

“|...¿’        | List of base 250 integers, [1960852478, 2251799815782398, 2143287262]
       ḃ2      | Convert to bijective base 2
         ’     | Decrease by 1
          T€   | List of indices of true values for each list
            ị¢ | Index into helper link 2

Lien d'assistance 4 : listes ci-dessus de caractères latins énumérés et triés par ordre décroissant de longueur

¢         | Helper link 3 as a nilad
       Ɗ€ | For each list, the following three links as a monad
 Ė        | - Enumerate (i.e. prepend a sequential index starting at 1 to each member of the list)
    $Þ    | - Sort using, as a key, the following two links as a monad
  Ẉ       |   - Lengths of lists
   Ṫ      |   - Tail (this will be the length of the original character or characters)
      Ṛ   | - Reverse

Lien principal : Monade qui prend une chaîne Jelly comme argument et renvoie la chaîne Jelly traduite

Section 1 : Convertir les blocs morphémiques en points de code Unicode des caractères latins correspondants

Section 1.1 : Obtenez la liste des caractères latins nécessaires pour créer les blocs

3£      | Helper link 3 as a nilad (lists of Latin characters used for Choseong, Jungseong and Jongseong)
  O     | Convert to Unicode code points
   Ż€3¦ | Prepend a zero to the third list (Jongseong)

Section 1.2 : Créez toutes les combinaisons de ces lettres (19 × 21 × 28 = 11 172 combinaisons dans l'ordre lexical approprié)

Œp      | Cartesian product
     Ɗ€ | For each combination:
  F     | - Flatten
   ḟ0   | - Filter zero (i.e. combinations with an empty Jonseong)

Section 1.3 : Associez les points de code Unicode des blocs avec la liste correspondante de caractères latins et utilisez-les pour traduire les blocs morphémiques dans la chaîne d'entrée

       Ʋ   | Following as a monad
J          | - Sequence from 1..11172
 +“Ḥœ’     | - Add 44031
      ,    | - Pair with the blocks themelves
        y  | Translate the following using this pair of lists
         O | - The input string converted to Unicode code points

Section 2 : convertir les caractères coréens individuels dans la sortie de la section 1 en points de code de l'équivalent latin

          ¤  | Following as a nilad
2£           | Helper link 2 (list of Latin characters/character pairs in the order that corresponds to the Unicode order of the Korean characters)
  O          | Convert to Unicode code points
         Ʋ   | Following as a monad:
   J         | - Sequence along these (from 1..51)
    +⁽.[     | - Add 12592
        ,    | - Pair with list of Latin characters
           y | Translate the output from section 1 using this mapping

Section 3 : Ranger les caractères non traduits dans la sortie de la section 2 (fonctionne parce que tout ce qui est traduit du coréen sera maintenant dans une sous-liste et aura donc la profondeur 1)

  ŒḊ?€  | For each member of list if the depth is 1:
¹       | - Keep as is
 Ọ      | Else: convert back from Unicode code points to characters
      µ | Start a new monadic chain using the output from this section as its argument

Section 4 : Convertir des blocs morphémiques de caractères latins en coréen

Section 4.1 : Obtenez toutes les combinaisons possibles de Choseong et Jungseong

¢    | Helper link 4 (lists of Latin characters enumerated and sorted in decreasing order of length)
 Ṗ   | Discard last list (Jongseong)
  Œp | Cartesian product

Section 4.2 : Étiquetez chaque combinaison avec le point de code Unicode pour le bloc morphémique de base (c'est-à-dire sans Jongseong)

                       Ʋ€ | For each Choseong/Jungseong combination
Z                         | - Transpose, so that we now have e.g. [[1,1],["r","k"]]
 F€                       | - Flatten each, joining the strings together
                    ʋ/    | - Reduce using the following as a dyad (effectively using the numbers as left argument and string of Latin characters as right)
                Ʋ         |   - Following links as a monad
   ’                      |     - Decrease by 1
    ḋ588,28               |     - Dot product with 21×28,28
           +“Ḥþ’          |     - Add 44032
                 0;       |     - Prepend zero; used for splitting in section 4.3 before each morphemic block (Ż won’t work because on a single integer it produces a range)
                   ,      |     - Pair with the string of Latin characters
                      Ṛ   |   - Reverse (so we now have e.g. ["rk", 44032]

Section 4.3 : Remplacez ces chaînes de caractères latins dans la sortie de la section 3 par les points de code Unicode du bloc morphémique de base

ñ   | Call helper link 1 (effectively search and replace)
 ṣ0 | Split at the zeros introduced in section 4.2

Section 4.4: Identifier s'il existe un Jongseong dans chaque bloc morphémique

                                        Ʋ | Following as a monad:
Ḋ                                         | - Remove the first sublist (which won’t contain a morphemic block; note this will be restored later)
                                     €    | - For each of the other lists Z returned by the split in section 4.3 (i.e. each will have a morphemic block at the beginning):
                                  Ʋ©?     |   - If the following is true (capturing its value in the register in the process) 
             Ḋ                            |     - Remove first item (i.e. the Unicode code point for the base morphemic block introduced in section 4.3)
              ;⁶                          |     - Append a space (avoids ending up with an empty list if there is nothing after the morphemic block code point)
                                          |       (Output from the above will be referred to as X below)
                                ¤         |       * Following as a nilad (call this Y):
                        ¢                 |         * Helper link 4
                         Ṫ                |         * Jongseong
                              Ʋ€          |         * For each Jongseong Latin list:
                          Ẉ               |           * Lengths of lists
                           Ṫ              |           * Tail (i.e. length of Latin character string)
                            ‘             |           * Increase by 1
                             ;            |           * Prepend this (e.g. [1, 1, "r"]
                     ¥Ƈ@                  |     - Filter Y using X from above and the following criteria
                Ṫ                         |       - Tail (i.e. the Latin characters for the relevant Jongseong
                 ⁼ṁ@¥                     |       - is equal to the beginning of X trimmed to match the relevant Jongseong (or extended but this doesn’t matter since no Jongseong are a double letter)
                                  Ḣ       |       - First matching Jongseong (which since they’re sorted by descending size order will prefer the longer one if there is a matching shorter one)
           Ɗ                              | - Then: do the following as a monad (note this is now using the list Z mentioned much earlier):
      Ɗ                                   |   - Following as a monad
 Ḣ                                        |     - Head (the Unicode code point of the base morphemic block)
  +®Ṫ¤                                    |     - Add the tail of the register (the position of the matched Jongsepng in the list of Jongseong)
       ;                                  |   - Concatenate to:
        ṫ®$                               |     - The rest of the list after removing the Latin characters representing the Jongseong
            ¹                             | - Else: leave the list untouched (no matching Jongseong)
                                       ṭ  | - Prepend:
                                        Ḣ |   - The first sublist from the split that was removed at the beginning of this subsection

Section 5 : Gérer les caractères latins restants qui correspondent aux caractères coréens mais ne font pas partie d'un bloc morphemuc

F                   | Flatten
                ¤   | Following as a nilad
 2£                 | - Helper link 2 (Latin characters/pairs of characters in Unicode order of corresponding Korean character)
          $         | - Following as a monad
   ż     Ɗ          |   - zip with following as a monad
    J               |     - Sequence along helper link 2 (1..51)
     +⁽.[           |     - Add 12592
             $Þ     | - Sort using following as key
           Ẉ        |   - Lengths of lists
            Ṫ       |   - Tail (i.e. length of Latin string)
               Ṛ    | - Reverse
                 ñ  | Call helper link 1 (search Latin character strings and replace with Korean code points)
                  Ọ | Finally, convert all Unicode code points back to characters and implicitly output
Nick Kennedy
la source
1
La sortie est fausse: quand je mets , j'excepte cor, mais ça donne cBor. Et cela ne change cpas . cana dû se convertir en ㅊ무, mais il s'est converti en c무. Et j'ai également excepté que les gros caractères qui n'apparaissent pas dans les spécifications seraient décapitalisés, mais cela peut être bien.
LegenDUST
@LegenDUST le problème c est résolu. J'ai utilisé Acomme espace réservé pour le deuxième caractère des caractères simples, et pour une raison quelconque, celui qui suivait cétait un B. La conversion en minuscules d'autres lettres pourrait être effectuée, mais ressemble à une complication inutile de ce qui est déjà un défi difficile.
Nick Kennedy
Je comprends que c'est difficile. J'ai donc ajouté une nouvelle règle: si vous décapitalisez, vous pouvez gagner 5 octets. Mais ça va.
LegenDUST
3

JavaScript (Node.js) , 587 582 575 569 557 554 550 549 octets

tfw vous ne le saviez pas string.charCodeAt() == string.charCodeAt(0).

s=>s.replace(eval(`/[ㄱ-힣]|${M="(h[kol]?|n[jpl]?|ml?|[bi-puyOP])"}|([${S="rRseEfaqQtTdwWczxvg"}])(${M}((s[wg]|f[raqtxvg]|qt|[${S}])(?!${M}))?)?/g`,L="r,R,rt,s,sw,sg,e,E,f,fr,fa,fq,ft,fx,fv,fg,a,q,Q,qt,t,T,d,w,W,c,z,x,v,g,k,o,i,O,j,p,u,P,h,hk,ho,hl,y,n,nj,np,nl,n,m,ml,l".split`,`,l=L.filter(x=>!/[EQW]/.test(x)),I="indexOf"),(a,E,A,B,C,D)=>a<"~"?E?X(E):A&&C?F(43193+S[I](A)*588+L[I](C)*28+l[I](D)):X(A)+X(C)+X(D):(b=a.charCodeAt()-44032)<0?L[b+31439]||a:S[b/588|0]+L[30+b/28%21|0]+["",...l][b%28],F=String.fromCharCode,X=n=>n?F(L[I](n)+12593):"")

Essayez-le en ligne!

547 si les caractères en dehors des alphabets et des jamos coréens peuvent être ignorés.

D'accord, j'ai lutté si longtemps pour écrire ceci, mais cela devrait fonctionner. Aucun jamo / syllabe coréen n'est utilisé car ils sont trop chers (3 octets par utilisation). Utilisé dans l'expression régulière pour enregistrer les octets.

s=>                                                    // Main Function:
 s.replace(                                            //  Replace all convertible strings:
  eval(
   `/                                                  //   Matching this regex:
    [ㄱ-힣]                                             //   ($0) All Korean jamos and syllables
    |${M="(h[kol]?|n[jpl]?|ml?|[bi-puyOP])"}           //   ($1) Isolated jungseong codes
    |([${S="rRseEfaqQtTdwWczxvg"}])                    //   ($2) Choseong codes (also acts as lookup)
     (                                                 //   ($3) Jungseong and jongseong codes:
      ${M}                                             //   ($4)  Jungseong codes
      (                                                //   ($5)  Jongseong codes:
       (                                               //   ($6)
        s[wg]|f[raqtxvg]|qt                            //          Diagraphs unique to jongseongs
        |[${S}]                                        //          Or jamos usable as choseongs
       ) 
       (?!${M})                                        //         Not linked to the next jungseong
      )?                                               //        Optional to match codes w/o jongseong
     )?                                                //       Optional to match choseong-only codes
   /g`,                                                //   Match all
   L="(...LOOKUP TABLE...)".split`,`,                  //   Lookup table of codes in jamo order
   l=L.filter(x=>!/[EQW]/.test(x)),                    //   Jongseong lookup - only first half is used
   I="indexOf"                                         //   [String|Array].prototype.indexOf
  ),
  (a,E,A,B,C,D)=>                                      //   Using this function:
   a<"~"?                                              //    If the match is code (alphabets):
    E?                                                 //     If isolated jungseongs code:
     X(E)                                              //      Return corresponding jamo
    :A&&C?                                             //     Else if complete syllable code:
     F(43193+S[I](A)*588+L[I](C)*28+l[I](D))           //      Return the corresponding syllable
    :X(A)+X(C)+X(D)                                    //     Else return corresponding jamos joined
   :(b=a.charCodeAt()-44032)<0?                        //    Else if not syllable:
    L[b+31439]||a                                      //     Return code if jamo (if not, ignore)
   :S[b/588|0]+L[30+b/28%21|0]+["",...l][b%28],        //    Else return code for the syllable
  F=String.fromCharCode,                               //   String.fromCharCode
  X=n=>                                                //   Helper function to convert code to jamo
   n?                                                  //    If not undefined:
    F(L[I](n)+12593)                                   //     Return the corresponding jamo
   :""                                                 //    Else return empty string
 )
Shieru Asakoto
la source
2

Wolfram Language (Mathematica) , 405 401 400 octets

c=CharacterRange
p=StringReplace
q=StringReverse
r=Reverse
t=Thread
j=Join
a=j[alphabet@"Korean",4520~c~4546]
x=j[#,r/@#]&@t[a->Characters@"rRseEfaqQtTdwWczxvgkoiOjpuPh"~j~StringSplit@"hk ho hl y n nj np nl b m ml l r R rt s sw sg e f fr fa fq ft fx fv fg a q qt t T d w c z x v g"]
y=t[""<>r@#&/@Tuples@TakeList[Insert[a,"",41]~p~x~p~x,{19,21,28}]->44032~c~55203]
f=q@p[q@#,#2]&
g=f[#,r/@y]~p~x~f~y&

Essayez-le en ligne!

Légèrement non golfé

Pour tester cela dans Mathematica, remplacez simplement alphabetpar Alphabet; cependant, TIO ne prend pas en charge Wolfram Cloud, je l'ai donc défini Alphabet["Korean"]dans l'en-tête.

Nous décomposons d'abord toutes les syllabes Hangul en alphabet Hangul, puis échangeons les caractères latins et Hangul, puis recomposons les syllabes.

lirtosiast
la source
1
Le cas de test input 2aboutit à la ㅑㅜㅔㅕㅅ 2place de ㅑㅞㅕㅅ 2votre TIO. Bien que la même chose se produise dans la solution sur laquelle je travaillais, car les deux et sont jungseong, et j'avais l'impression que seuls choseong + jungseong + jongseong ou choseong + jungseong + vide seraient combinés. J'ai demandé pourquoi OP pour la vérification ㅜㅔest devenu .
Kevin Cruijssen
@KevinCruijssen ㅞ (np) est une jungseong à part entière
Nick Kennedy
1
Cela ne semble pas fonctionner correctement pour deux consonnes ou voyelles de caractère. Par exemple, il fnpfadevrait s'agir d'un seul personnage, mais finit par devenir루ㅔㄹㅁ
Nick Kennedy
Correction en cours. Cela ne devrait pas coûter trop cher.
lirtosiast
2

Java 19, 1133 1126 1133 octets

s->{String r="",k="ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ",K[]=k.split(" "),a="r R s e E f a q Q t T d w W c z x v g k o i O j p u P h hk ho hl y n nj np nl b m ml l r R rt s sw sg e f fr fa fq ft fx fv fg a q qt t T d w c z x v g";var A=java.util.Arrays.asList(a.split(" "));k=k.replace(" ","");int i,z,y,x=44032;for(var c:s.toCharArray())if(c>=x&c<55204){z=(i=c-x)%28;y=(i=(i-z)/28)%21;s=s.replace(c+r,r+K[0].charAt((i-y)/21)+K[1].charAt(y)+(z>0?K[2].charAt(z-1):r));}for(var c:s.split(r))r+=c.charAt(0)<33?c:(i=k.indexOf(c))<0?(i=A.indexOf(c))<0?c:k.charAt(i):A.get(i);for(i=r.length()-1;i-->0;r=z>0?r.substring(0,i)+(char)(K[0].indexOf(r.charAt(i))*588+K[1].indexOf(r.charAt(i+1))*28+((z=K[2].indexOf(r.charAt(i+2)))<0?0:z+1)+x)+r.substring(z<0?i+2:i+3):r)for(z=y=2;y-->0;)z&=K[y].contains(r.charAt(i+y)+"")?2:0;for(var p:"ㅗㅏㅘㅗㅐㅙㅗㅣㅚㅜㅓㅝㅜㅔㅞㅜㅣㅟㅡㅣㅢ".split("(?<=\\G...)"))r=r.replace(p.substring(0,2),p.substring(2));return r;}

Sorties avec majuscules ASDFGHJKLZXCVBNMinchangées, car .toLowerCase()coûtent plus que le bonus -5.

Retour +7 octets comme correction de bogue pour les caractères non coréens au-dessus de la valeur unicode 20 000 (merci @NickKennedy pour l'avoir remarqué).

Essayez-le en ligne.

Explication:

s->{                         // Method with String as both parameter and return-type
  String r="",               //  Result-String, starting empty
         k="ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ",
                             //  String containing the Korean characters
         K[]=k.split(" "),   //  Array containing the three character-categories
         a="r R s e E f a q Q t T d w W c z x v g k o i O j p u P h hk ho hl y n nj np nl b m ml l r R rt s sw sg e f fr fa fq ft fx fv fg a q qt t T d w c z x v g"; 
                             //  String containing the English characters
  var A=java.util.Arrays.asList(a.split(" "));
                             //  List containing the English character-groups
  k=k.replace(" ","");       //  Remove the spaces from the Korean String
  int i,z,y,                 //  Temp integers
      x=44032;               //  Integer for 0xAC00
  for(var c:s.toCharArray()) //  Loop over the characters of the input:
    if(c>=x&c<55204){        //   If the unicode value is in the range [44032,55203]
                             //   (so a Korean combination character):
      z=(i=c-x)%28;          //    Set `i` to this unicode value - 0xAC00,
                             //    And then `z` to `i` modulo-28
      y=(i=(i-z)/28)%21;     //    Then set `i` to `i`-`z` integer divided by 28
                             //    And then `y` to `i` modulo-21
      s=s.replace(c+r,       //    Replace the current non-Korean character with:
        r+K[0].charAt((i-y)/21)
                             //     The corresponding choseong
         +K[1].charAt(y)     //     Appended with jungseong
         +(z>0?K[2].charAt(z-1):r));}
                             //     Appended with jongseong if necessary
  for(var c:s.split(r))      //  Then loop over the characters of the modified String:
    r+=                      //   Append to the result-String:
       c.charAt(0)<33?       //    If the character is a space:
        c                    //     Simply append that space
       :(i=k.indexOf(c))<0?  //    Else-if the character is NOT a Korean character:
         (i=A.indexOf(c))<0? //     If the character is NOT in the English group List:
          c                  //      Simply append that character
         :                   //     Else:
          k.charAt(i)        //      Append the corresponding Korean character
       :                     //    Else:
        A.get(i);            //     Append the corresponding letter
  for(i=r.length()-1;i-->0   //  Then loop `i` in the range (result-length - 2, 0]:
      ;                      //    After every iteration:
       r=z>0?                //     If a group of Korean characters can be merged:
          r.substring(0,i)   //      Leave the leading part of the result unchanged
          +(char)(K[0].indexOf(r.charAt(i))
                             //      Get the index of the first Korean character,
                   *588      //      multiplied by 588
                  +K[1].indexOf(r.charAt(i+1))
                             //      Get the index of the second Korean character,
                   *28       //      multiplied by 28
                  +((z=K[2].indexOf(r.charAt(i+2)))
                             //      Get the index of the third character
                    <0?      //      And if it's a Korean character in the third group:
                      0:z+1) //       Add that index + 1
                  +x         //      And add 0xAC00
                 )           //      Then convert that integer to a character
          +r.substring(z<0?i+2:i+3) 
                             //      Leave the trailing part of the result unchanged as well
         :                   //     Else (these characters cannot be merged)
          r)                 //      Leave the result the same
     for(z=y=2;              //   Reset `z` to 2
         y-->0;)             //   Inner loop `y` in the range (2, 0]:
       z&=                   //    Bitwise-AND `z` with:
         K[y].contains(      //     If the `y`'th Korean group contains
           r.charAt(i+y)+"")?//     the (`i`+`y`)'th character of the result
          2                  //      Bitwise-AND `z` with 2
         :                   //     Else:
          0;                 //      Bitwise-AND `z` with 0
                             //   (If `z` is still 2 after this inner loop, it means
                             //    Korean characters can be merged)
  for(var p:"ㅗㅏㅘㅗㅐㅙㅗㅣㅚㅜㅓㅝㅜㅔㅞㅜㅣㅟㅡㅣㅢ".split("(?<=\\G...)"))
                             //  Loop over these Korean character per chunk of 3:
    r=r.replace(p.substring(0,2),
                             //   Replace the first 2 characters in this chunk
         p.substring(2));    //   With the third one in the result-String
  return r;}                 //  And finally return the result-String
Kevin Cruijssen
la source
1
ils sont de 44032 à 55203. Vous avez déjà codé l'emplacement de départ. La fin est juste44032 + 19×21×28 - 1
Nick Kennedy
Fonctionne bien maintenant. Je pensais que j'avais déjà voté pour toi mais que non, alors voilà!
Nick Kennedy