Korece iki setli klavye ve qwerty klavye arasında dönüştürme


14

Giriş

DVORAK Klavye düzenine benziyor , ancak çok daha zor.

Önce Korece klavye hakkında konuşalım. Wikipedia'da görebileceğiniz gibi , Korece ve İngilizce anahtar kümeleri arasında geçiş yapmak için bir Kor / Eng anahtarı vardır.

Koreliler bazen yanlış yazıyorlar: qwerty klavyede Korece veya iki setli klavyede İngilizce yazmaya çalışıyorlar.

Yani, sorun şu: iki setli klavyede yazılmış Korece karakterler verilirse, qwerty klavyede yazılmış alfabetik karakterlere dönüştürün. Qwerty ile yazılmış alfabetik karakterler verildiyse, bunu iki setli klavyeyle değiştirin.

İki Setli Klavye

İşte iki setli klavye düzeni:

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

ve üst karakter tuşuyla:

ㅃㅉㄸㄲㅆㅛㅕㅑㅒㅖ

diğerleri değil sadece üst sıra değişir.

Korece Karakterler Hakkında

burada biterse, kolay olabilir, ama hayır. Yazdığınızda

dkssud, tprP!

çıktı şu şekilde gösterilmez:

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

ama bu şekilde:

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

ve işleri daha da zorlaştırıyor.

Korece Karakterler üç bölüme ayrılır: 'Choseong (ünsüz)', 'Jungseong (Ünlü)' ve 'Jongseong (hecenin sonunda ünsüz: boş olabilir)' ve ayırmanız gerekir.

Neyse ki, bunu yapmanın bir yolu var.

Nasıl ayrılabilir

19 Choseong, 21 Jungseong ve 28 Jongseong (boşluklu) var ve 0xAC00 Korece karakterlerin ilk karakteri olan '가'. Bunu kullanarak Korece karakterleri üç parçaya ayırabiliriz. İşte her birinin sırası ve iki setli klavyedeki konumu.

choseong sipariş:

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

jungseong sipariş:

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

jongseong sipariş:

()ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ
()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

Diyelim diyelim (unicode value of some character) - 0xAC00olduğunu Korean_codeve CHOSEONG, Jungseong endeksi, Jongseong olduğunu Cho, Jung, Jong.

Sonra Korean_codeise(Cho * 21 * 28) + Jung * 28 + Jong

Rahatınız için Korece karakteri bu Korece web sitesinden ayıran javascript kodu .

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

Monte edildiğinde

  1. Not , , , , , , diğer jungseongs bir kombinasyonudur.
ㅗ+ㅏ=ㅘ, ㅗ+ㅐ=ㅙ, ㅗ+ㅣ=ㅚ, ㅜ+ㅓ=ㅝ, ㅜ+ㅔ=ㅞ, ㅜ+ㅣ=ㅟ, ㅡ+ㅣ=ㅢ
  1. Choseong gerekli. Bu frk, verilirse, ㄹㄱㅏiki şekilde değişebileceği anlamına gelir : ㄺㅏve ㄹ가. Sonra, choseong olan bir şekilde dönüştürmek zorunda. Eğer jjjrjrverilen hangi ㅓㅓㅓㄱㅓㄱlider ler CHOSEONG edilebilir bir şey yok, ama dördüncü vardır o içine değişti böylece, o CHOSEONG edilebilir ㅓㅓㅓ걱.

Başka bir örnek: 세계( tprP). 섹ㅖ( (ㅅㅔㄱ)(ㅖ)) Olarak değiştirilebilir , ancak choseong gerekli olduğundan, 세계( (ㅅㅔ)(ㄱㅖ)) olarak değiştirilir

Örnekler

girdi 1

안녕하세요

çıktı 1

dkssudgktpdy

girdi 2

input 2

çıktı 2

ㅑㅞㅕㅅ 2

girdi 3

힘ㄴㄴ

çıktı 3

glass

girdi 4

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

çıktı 4

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

girdi 5

dkssud, tprP!

çıktı 5

안녕, 세계!

girdi 6

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

çıktı 6

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

En kısa kod kazanır. (bayt cinsinden)

Size kolaylık sağlamak için yeni kural

Aİki setli klavyede benzerleri olmayan karakterleri kapatabilirsiniz . böylece Aheuiiçin Aㅗ뎌ㅑsorun yok. Değiştirmek Ama eğer Aheuiüzere 모뎌ㅑ, alabilirsiniz -5 noktası, sen 5 bayt kazanabilmesi için.

Sen (gibi iki jungseongs ayırabilirsiniz için ㅗ+ㅏ). gibi rhkhiç 고ㅏveya howhiç ㅗㅐㅈ. Eğer (gibi birleştirin Ama eğer rhkhiç ya howkadar ㅙㅈ), ek -5 puan kazanabilirsiniz.


Gelen Jungseong sipariş harflerin bölüm birinde eksik. 21 Koreli sembol görüyorum, ancak sadece 20 harf (-çift) s. DÜZENLEME: Bir trialing eksik görünüyor lsonra mlKoreli sembolü için .
Kevin Cruijssen

@KevinCruijssen düzenledi. l için.
LegenDUST

1
Bazen birden fazla yorum olabilir. Örneğin, veya fjfauolarak yorumlanabilir . Bunu nasıl çözeriz? 럶ㅕ럴며
Nick Kennedy

1
@LegenDUST Tek bir Korece kelime okuyamıyorum, bu yüzden açıklaman gerekecek. ; gelince s tprPtesti durumda 5: Bu dönüşümler ㅅㅔㄱㅖ, bir CHOSEONG olan, bir Jungseong ve bir jongseong olup. Yani bu dönüşmek should't 섷ㅖ(gibi gruplandırılmış (ㅅㅔㄱ)(ㅖ)) yerine 세계(gibi gruplandırılmış (ㅅㅔ)(ㄱㅖ))? Daha önceki bir yorumda, yazarak yorumlandığını belirtiyorsunuz, bu yüzden ㅅㅔㄱdönüşmeyi bekliyordum . Veya Korece yazım soldan sağa değil sağdan sola mı?
Kevin Cruijssen

1
@KevinCruijssen Unicode.org'dan PDF dosyası . AC00 ( ) ila D7AF ( ) arasındadır.
LegenDUST

Yanıtlar:


6

Jöle , 296264 bayt

Ẏœṣ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+⁽.[Ɗ$ẈṪ$ÞṚ¤ñỌ

Çevrimiçi deneyin!

Bir dizeyi bağımsız değişkeni olarak alan ve (dolaylı olarak yazdırılan) bir dize döndüren tam bir program. Bu üç geçişte çalışır: ilk olarak tüm Korece karakterleri Latin harfleri için kod noktaları listesine dönüştürür. Daha sonra bileşik Korece karakterleri tanımlar ve oluşturur. Son olarak, kalan Latin harflerini Kore eşdeğerine çevirir. Spesifikasyonda görünmeyen diğer karakterlerin ve Latin harflerinin (örn. A) Yalnız bırakıldığını unutmayın.

Spesifikasyonlar dışındaki küçük harflerin küçük harflere dönüştürülmesi gerekiyorsa, bu ek 10 baytlık bir maliyetle yapılabilir .

açıklama

Yardımcı bağlantı 1 : x ve y değişkenleriyle ikili bağlantı. x, arama ve değiştirme alt listelerinin çiftlerinin bir listesidir. y, her bir arama alt listesini karşılık gelen değiştirme alt listesiyle değiştirir

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

Yardımcı bağlantı 2 : Korece karakterlerin Unicode sırasına karşılık gelen sırayla Latin karakterlerin / karakter çiftlerinin listesi

“Ȯ..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)

Yardımcı bağlantı 3 : Choseong, Jungseong ve Jongseong için kullanılan Latin karakterlerinin listesi

“|...¿’        | 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

Yardımcı bağlantı 4 : Azalan uzunluk sırasına göre numaralandırılan ve sıralanan Latin karakter listelerinin üstünde

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

Ana bağlantı : Jelly dizesini argüman olarak alan ve çevrilmiş Jelly dizesini döndüren Monad

Bölüm 1 : Morfemik blokları karşılık gelen Latin karakterlerinin Unicode kod noktalarına dönüştürün

Bölüm 1.1 : Blokları yapmak için gereken Latin karakterlerinin listesini alın

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)

Bölüm 1.2 : Bu harflerin tüm kombinasyonlarını oluşturun (19 × 21 × 28 = 11,172 kombinasyonları uygun sözcük sırasına göre)

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

Bölüm 1.3 : Blokların Unicode kod noktalarını karşılık gelen Latin karakterleri listesiyle eşleştirin ve bunları giriş dizesindeki morfemik blokları çevirmek için kullanın

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

Bölüm 2 : Çıktıdaki Korece karakterleri bölüm 1'den Latin eşdeğerinin kod noktalarına dönüştürün

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

Bölüm 3 : Bölüm 2'nin çıktısında çevrilmemiş karakterleri toplayın (Korece tercüme edilen her şey bir alt listede olacağı için derinlik 1 olduğu için işe yarıyor)

  ŒḊ?€  | 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

Bölüm 4 : Latin karakterlerinin morfemik bloklarını Korece'ye dönüştürme

Bölüm 4.1 : Tüm olası Choseong ve Jungseong kombinasyonlarını alın

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

Bölüm 4.2 : Her kombinasyonu temel morfemik blok için Unicode kod noktasıyla etiketleyin (örn. Jongseong olmadan)

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

Bölüm 4.3 : Bölüm 3'teki çıktıdaki bu Latin karakter dizelerini temel morfemik bloğun Unicode kod noktaları ile değiştirin

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

Bölüm 4.4: Her bir morfemik bloğun bir parçası olarak bir Jongseong olup olmadığını belirleyin

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

Bölüm 5 : Korece karakterlerle eşleşen ancak bir morphemuc bloğunun parçası olmayan kalan Latin karakterlerini kullanın

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

1
Çıktı yanlış: Koyduğumda cor, istisna ettim , ama verdi cBor. Ve bu değişmez ciçin . candönüşmek zorunda kaldı ㅊ무, ama dönüştü c무. Ayrıca, spesifikasyonlarda görünmeyen büyük karakterlerin dehşete düşürüleceğini de hariç tuttum, ancak iyi olabilir.
LegenDUST

@LegenDUST c sorunu düzeltildi. ATek karakterlerin ikinci karakteri için yer tutucu olarak kullandım ve bir sebepten sonra bir karakter colarak ortaya çıktı B. Diğer harflerin küçük harflerine dönüştürme yapılabilir, ancak zaten zor olan bir şey için gereksiz bir komplikasyon gibi hissedilir.
Nick Kennedy

Bunun zor olduğunu anlıyorum. Bu yüzden yeni bir kural ekledim: başını keserseniz 5 bayt kazanabilirsiniz. Ama bu iyi.
LegenDUST

3

JavaScript (node.js) , 587 582 575 569 557 554 550 549 bayt

Bunu bilmiyordun 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):"")

Çevrimiçi deneyin!

Alfabe ve kore jamosunun dışındaki karakterler göz ardı edilebilirse.

Tamam, bunu yazmak için uzun süre uğraştım, ama bu işe yaramalı. Hiçbir Kore jamo / hece kullanılmaz çünkü çok pahalıdırlar (kullanım başına 3 bayt). Normal ifadede bayt kaydetmek için kullanılır.

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
 )

2

Wolfram Dili (Mathematica) , 405 401 , 400 bayt

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&

Çevrimiçi deneyin!

Hafifçe soluksuz

Sadece yerine Mathematica Bunu sınamak için alphabetbirlikte Alphabet; ancak TIO, Wolfram Cloud'u desteklemediğinden Alphabet["Korean"]başlıkta tanımladım .

Önce tüm Hangul hecelerini Hangul alfabesine ayırırız, sonra Latin ve Hangul karakterlerini değiştiririz, sonra heceleri yeniden düzenleriz.


1
Vaka input 2sonuçlarını TIO'nuz ㅑㅜㅔㅕㅅ 2yerine test ㅑㅞㅕㅅ 2edin. Aynı çözeltide olur rağmen ben hem beri üzerinde çalıştığı ve Jungseong, ve ben sadece CHOSEONG + Jungseong + jongseong veya CHOSEONG + Jungseong + boş kombine olacağını sanmıştım. Neden doğrulama için OP sorulan ㅜㅔoldu .
Kevin Cruijssen

@KevinCruijssen ㅞ (np) kendi başına bir jungseong
Nick Kennedy

1
Bu, iki karakter ünsüzleri veya sesli harfleri için düzgün çalışmıyor gibi görünüyor. Mesela fnpfatek bir karakter olmalı ama onun yerine şöyle bitecek루ㅔㄹㅁ
Nick Kennedy

Düzeltme devam ediyor. Çok pahalıya mal olmamalı.
lirtosiast

2

Java 19, 1133 1126 1133 bayt

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;}

Büyük harfli çıktılar ASDFGHJKLZXCVBNMdeğişmedi, çünkü .toLowerCase()maliyeti -5 bonusdan daha fazla.

Korece olmayan karakterler için unicode değeri 20.000'in üzerinde bir hata düzeltmesi olarak +7 bayt geri döndü (fark ettiğiniz için @NickKennedy'e teşekkürler ).

Çevrimiçi deneyin.

Açıklama:

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

1
44032 ile 55203 arasındalar. Zaten başlangıç ​​konumu kodlu. Son sadece44032 + 19×21×28 - 1
Nick Kennedy

Şimdi iyi çalışıyor. Seni zaten iptal ettiğimi sanmıştım ama yapmamıştım, işte böyle!
Nick Kennedy
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.