Konversi antara keyboard dua set Korea dan keyboard qwerty


14

pengantar

Ini agak seperti tata letak Keyboard DVORAK , tapi JAUH lebih keras.

Mari kita bicara tentang keyboard Korea terlebih dahulu. Seperti yang Anda lihat di Wikipedia , ada kunci Kor / Eng untuk mengubah antara set kunci Korea dan Inggris.

Orang Korea terkadang salah ketik: mereka mencoba menulis dalam bahasa Korea pada keyboard qwerty atau dalam bahasa Inggris pada keyboard dua set.

Jadi, inilah masalahnya: jika diberikan karakter Korea yang diketik dalam keyboard dua set, ubahlah ke karakter alfabet yang diketik dalam keyboard qwerty. Jika diberi karakter alfabet yang diketik dalam qwerty, ubah ke keyboard dua set.

Keyboard dua set

Berikut adalah tata letak keyboard dua-set:

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

dan dengan tombol shift:

ㅃㅉㄸㄲㅆㅛㅕㅑㅒㅖ

hanya baris atas yang berubah sementara yang lain tidak.

Tentang Karakter Korea

jika berakhir di sini, itu bisa mudah, tetapi tidak. Saat Anda mengetik

dkssud, tprP!

output tidak ditampilkan dengan cara ini:

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

tetapi dengan cara ini:

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

dan itu membuat segalanya menjadi lebih sulit.

Karakter Korea terpisah menjadi tiga bagian: 'Choseong (konsonan)', 'Jungseong (Vowel)', dan 'Jongseong (konsonan di akhir suku kata: bisa kosong)', dan Anda harus memisahkannya.

Untungnya, ada cara untuk melakukan itu.

Cara memisahkan

Ada 19 Choseong, 21 Jungseong, dan 28 Jongseong (dengan kosong), dan 0xAC00 adalah '가', karakter pertama dari karakter Korea. Dengan ini, kita dapat memisahkan karakter Korea menjadi tiga bagian. Berikut adalah urutan masing-masing dan posisinya di keyboard dua set.

Pesananong:

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

pesanan jungseong:

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

pesanan 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

Mari mengatakan (unicode value of some character) - 0xAC00adalah Korean_code, dan indeks Choseong, Jungseong, Jongseong adalah Cho, Jung,Jong .

Lalu, Korean_codeadalah(Cho * 21 * 28) + Jung * 28 + Jong

Berikut adalah kode javascript yang memisahkan karakter Korea dari situs web Korea ini, untuk kenyamanan Anda.

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

Saat dirakit

  1. Perhatikan bahwa , , , , , , adalah kombinasi dari jungseongs lainnya.
ㅗ+ㅏ=ㅘ, ㅗ+ㅐ=ㅙ, ㅗ+ㅣ=ㅚ, ㅜ+ㅓ=ㅝ, ㅜ+ㅔ=ㅞ, ㅜ+ㅣ=ㅟ, ㅡ+ㅣ=ㅢ
  1. Choseong diperlukan. Itu berarti, jika frkdiberikan, yang ㄹㄱㅏdapat berubah dalam dua cara: ㄺㅏdan ㄹ가. Kemudian, Anda harus mengubahnya menjadi cara yang telah memilih. Jika jjjrjrdiberikan, yaitu ㅓㅓㅓㄱㅓㄱ, pemimpin tidak memiliki apa pun yang dapat dipilih, tetapi yang keempat memiliki dapat dipilih, sehingga diubah menjadi ㅓㅓㅓ걱.

Contoh lain: 세계( tprP). Itu dapat diubah menjadi 섹ㅖ( (ㅅㅔㄱ)(ㅖ)), tetapi karena memilihong diperlukan, itu diubah menjadi 세계( (ㅅㅔ)(ㄱㅖ))

Contohnya

masukan 1

안녕하세요

output 1

dkssudgktpdy

masukan 2

input 2

output 2

ㅑㅞㅕㅅ 2

masukan 3

힘ㄴㄴ

keluaran 3

glass

masukan 4

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

keluaran 4

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

masukan 5

dkssud, tprP!

output 5

안녕, 세계!

input 6

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

output 6

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

Kode terpendek menang. (dalam byte)

Aturan baru untuk kenyamanan Anda

Anda dapat mengabaikan karakter seperti Ayang tidak memiliki pasangannya di papan ketik dua set. sehingga Aheuiuntuk Aㅗ뎌ㅑOK. Tapi, jika Anda mengubah Aheuike모뎌ㅑ , Anda bisa mendapatkan -5 poin, sehingga Anda bisa mendapatkan 5 byte.

Anda dapat memisahkan dua jungseongs (seperti untuk ㅗ+ㅏ). seperti rhkuntuk 고ㅏ, atau howuntuk ㅗㅐㅈ. Tapi jika Anda menggabungkan itu (seperti rhkuntuk atau howke ㅙㅈ), Anda bisa mendapatkan tambahan -5 poin.


Di bagian urutan jungseong salah satu surat hilang. Saya melihat 21 simbol Korea, tetapi hanya 20 huruf (-pair) s. EDIT: Tampaknya akan hilang uji coba lsetelah mluntuk simbol Korea .
Kevin Cruijssen

@KevinCruijssen diedit. l untuk ㅣ.
LegenDUST

1
Terkadang ada lebih dari satu interpretasi. Misalnya, fjfaubisa diartikan sebagai 럶ㅕatau 럴며. Bagaimana kita menyelesaikan ini?
Nick Kennedy

1
@LegenDUST Yah, saya tidak bisa membaca satu kata Korea, jadi saya harus pergi dengan penjelasan Anda. ; p Adapun tprPdalam kasus uji 5: ini berubah menjadi ㅅㅔㄱㅖ, di mana Choongong, adalah jungseong dan adalah sebuah tongong. Jadi bukankah seharusnya ini berubah menjadi 섷ㅖ(dikelompokkan seperti (ㅅㅔㄱ)(ㅖ)), bukan 세계(dikelompokkan seperti (ㅅㅔ)(ㄱㅖ))? Dalam komentar sebelumnya Anda menyatakan itu ditafsirkan dengan mengetik, jadi saya berharap ㅅㅔㄱuntuk berubah menjadi . Atau apakah pengetikan bahasa Korea dari kanan ke kiri bukan dari kiri ke kanan?
Kevin Cruijssen

1
@KevinCruijssen file PDF dari Unicode.org. AC00 ( ) ke D7AF ( ).
LegenDUST

Jawaban:


6

Jelly , 296 264 byte

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

Cobalah online!

Program lengkap yang menggunakan string sebagai argumennya dan mengembalikan string (yang dicetak secara implisit). Ini berfungsi dalam tiga lintasan: pertama itu mengkonversi semua karakter Korea ke daftar titik kode untuk huruf Latin. Kemudian itu mengidentifikasi dan membangun karakter Korea gabungan. Akhirnya, itu mengubah setiap huruf Latin liar yang tersisa menjadi setara dengan Korea. Perhatikan bahwa karakter lain dan huruf Latin yang tidak muncul dalam spesifikasi (misA ) Dibiarkan sendiri.

Jika konversi ke huruf kecil huruf luar spec diperlukan, ini dapat dilakukan dengan biaya tambahan 10 byte .

Penjelasan

Helper link 1 : link diad dengan argumen x dan y. x adalah daftar pasangan pencarian dan ganti sublists. y akan setiap sublist pencarian diganti dengan sublist pengganti yang sesuai

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

Tautan bantuan 2 : Daftar karakter Latin / pasangan karakter dalam urutan yang sesuai dengan urutan Unicode dari karakter Korea

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

Helper link 3 : Daftar karakter Latin yang digunakan untuk Choseong, Jungseong dan 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

Tautan bantuan 4 : Di atas daftar karakter Latin yang disebutkan dan diurutkan dalam urutan panjang yang menurun

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

Tautan utama : Monad yang menggunakan string Jelly sebagai argumennya dan mengembalikan string Jelly yang diterjemahkan

Bagian 1 : Ubah blok morfemik menjadi titik kode Unicode dari karakter Latin yang sesuai

Bagian 1.1 : Dapatkan daftar karakter Latin yang diperlukan untuk membuat blok

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)

Bagian 1.2 : Buat semua kombinasi huruf-huruf ini (19 × 21 × 28 = 11.172 kombinasi dalam urutan leksikal yang sesuai)

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

Bagian 1.3 : Pasangkan titik kode Unicode dari blok dengan daftar karakter Latin yang sesuai, dan gunakan ini untuk menerjemahkan blok morfemik dalam string input

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

Bagian 2 : Konversi karakter Korea individu di output dari bagian 1 ke titik kode setara 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

Bagian 3 : Rapikan karakter yang tidak diterjemahkan dalam output dari bagian 2 (berfungsi karena apa pun yang diterjemahkan dari bahasa Korea sekarang akan berada dalam sublist dan karenanya memiliki kedalaman 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

Bagian 4 : Ubah blok morfemik karakter Latin menjadi bahasa Korea

Bagian 4.1 : Dapatkan semua kemungkinan kombinasi Choseong dan Jungseong

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

Bagian 4.2 : Beri label setiap kombinasi dengan titik kode Unicode untuk blok morfemik dasar (yaitu tanpa 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]

Bagian 4.3 : Ganti string karakter Latin ini dalam output dari bagian 3 dengan titik kode Unicode dari blok morfemik dasar

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

Bagian 4.4: Identifikasi apakah ada Jongseong sebagai bagian dari setiap blok morfemik

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

Bagian 5 : Tangani karakter Latin yang tersisa yang cocok dengan karakter Korea tetapi bukan bagian dari blok 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

1
Keluaran salah: Ketika saya memasukkan , saya mengecualikan cor, tetapi hasilnya memberi cBor. Dan itu tidak berubah cmenjadi . canharus dikonversi menjadi ㅊ무, tetapi diubah menjadi c무. Dan saya juga mengecualikan karakter besar yang tidak muncul dalam spec akan dipenggal, tetapi bisa baik-baik saja.
LegenDUST

@ LegenDUST masalah c diperbaiki. Saya digunakan Asebagai pengganti untuk karakter kedua dari karakter tunggal, dan untuk beberapa alasan setelah citu keluar sebagai a B. Konversi ke huruf kecil huruf lain bisa dilakukan, tetapi terasa seperti komplikasi yang tidak perlu untuk apa yang sudah merupakan tantangan yang sulit.
Nick Kennedy

Saya mengerti ini sulit. Jadi saya menambahkan aturan baru: jika Anda memenggal kepala, Anda bisa mendapatkan 5 byte. Tapi ini baik-baik saja.
LegenDUST

3

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

Jika Anda tidak tahu itu 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):"")

Cobalah online!

547 jika karakter di luar huruf dan jamo korea dapat diabaikan.

Oke saya sudah berjuang begitu lama untuk menulis ini, tetapi ini seharusnya berhasil. Jamo / suku kata Korea tidak digunakan karena terlalu mahal (3 byte per penggunaan).Digunakan dalam ekspresi reguler untuk menyimpan byte.

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

Bahasa Wolfram (Mathematica) , 405 401 400 byte

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&

Cobalah online!

Sedikit tidak berbulu

Untuk menguji ini di Mathematica cukup ganti alphabetdengan Alphabet; namun, TIO tidak mendukung Cloud Wolfram, jadi saya mendefinisikanAlphabet["Korean"] di header.

Kami pertama-tama mendekomposisi semua suku kata Hangul ke alfabet Hangul, kemudian bertukar karakter Latin dan Hangul, kemudian mengomposisi ulang suku kata tersebut.


1
Uji kasus input 2menghasilkan ㅑㅜㅔㅕㅅ 2bukan ㅑㅞㅕㅅ 2dalam TIO Anda. Meskipun hal yang sama terjadi pada solusi yang saya kerjakan, karena keduanya dan jungseong, dan saya berada di bawah kesan hanya memilihong + jungseong + jongseong atau Chooseong + jungseong + kosong akan digabungkan. Aku bertanya OP untuk verifikasi mengapa ㅜㅔmenjadi .
Kevin Cruijssen

@KevinCruijssen ㅞ (np) adalah jungseong dengan haknya sendiri
Nick Kennedy

1
Ini sepertinya tidak berfungsi dengan baik untuk dua karakter konsonan atau vokal. Misalnya fnpfaharus karakter tunggal tetapi berakhir sebagai루ㅔㄹㅁ
Nick Kennedy

Perbaiki sedang berlangsung. Seharusnya tidak terlalu mahal.
lirtosiast

2

Java 19, 1133 1126 1133 byte

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

Output dengan huruf kapital ASDFGHJKLZXCVBNMtidak berubah, sejak.toLowerCase() biayanya lebih dari -5 bonus.

Kembalikan +7 byte sebagai perbaikan bug untuk karakter non-Korea di atas nilai unicode 20.000 (terima kasih @NickKennedy karena memperhatikan).

Cobalah online.

Penjelasan:

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
mereka dari 44032 hingga 55203. Anda sudah mendapatkan kode lokasi awal. Akhirnya hanya44032 + 19×21×28 - 1
Nick Kennedy

Sekarang bekerja dengan baik. Kupikir aku sudah memilihmu tapi tidak, jadi ini dia!
Nick Kennedy
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.