Chuyển đổi giữa bàn phím hai bộ Hàn Quốc và bàn phím qwerty


14

Giới thiệu

Nó hơi giống bố trí bàn phím DVORAK , nhưng RẤT NHIỀU.

Trước tiên hãy nói về bàn phím tiếng Hàn. Như bạn có thể thấy trong Wikipedia , có một khóa Kor / Eng để thay đổi giữa các bộ khóa tiếng Hàn và tiếng Anh.

Người Hàn đôi khi gõ sai: họ cố gắng viết bằng tiếng Hàn trên bàn phím qwerty hoặc bằng tiếng Anh trên bàn phím hai bộ.

Vì vậy, đây là vấn đề: nếu đưa ra các ký tự tiếng Hàn được gõ trong bàn phím hai bộ, hãy chuyển đổi nó thành các ký tự chữ cái được gõ trong bàn phím qwerty. Nếu được cung cấp các ký tự chữ cái được gõ bằng qwerty, hãy đổi nó thành bàn phím hai bộ.

Bàn phím hai bộ

Đây là cách bố trí bàn phím hai bộ:

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

và với phím shift:

ㅃㅉㄸㄲㅆㅛㅕㅑㅒㅖ

chỉ hàng trên cùng thay đổi trong khi những người khác thì không.

Về nhân vật Hàn Quốc

nếu nó kết thúc ở đây, nó có thể dễ dàng, nhưng không. Khi bạn gõ

dkssud, tprP!

đầu ra không được hiển thị theo cách này:

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

nhưng theo cách này:

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

và nó làm cho mọi thứ khó khăn hơn nhiều.

Các ký tự tiếng Hàn tách thành ba phần: 'Choseong (phụ âm)', 'Jungseong (nguyên âm)' và 'Jongseong (phụ âm ở cuối âm tiết: có thể để trống)', và bạn phải tách nó ra.

May mắn thay, có cách để làm điều đó.

Cách tách

Có 19 Choseong, 21 Jungseong và 28 Jongseong (trống) và 0xAC00 là '가', nhân vật đầu tiên của các nhân vật Hàn Quốc. Sử dụng điều này, chúng ta có thể tách các ký tự tiếng Hàn thành ba phần. Dưới đây là thứ tự của mỗi và vị trí của nó trong bàn phím hai bộ.

đơn hàng đã chọn:

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

trật tự rừng rậm:

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

thứ tự 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

Hãy nói (unicode value of some character) - 0xAC00Korean_code, và chỉ số của đệm Choseong, tự đệm Jungseong, Jongseong là Cho, Jung, Jong.

Sau đó, Korean_code(Cho * 21 * 28) + Jung * 28 + Jong

Đây là mã javascript tách biệt ký tự tiếng Hàn khỏi trang web tiếng Hàn này, để thuận tiện cho bạn.

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

Khi lắp ráp

  1. Lưu ý rằng , , , , , , là sự kết hợp của jungseongs khác.
ㅗ+ㅏ=ㅘ, ㅗ+ㅐ=ㅙ, ㅗ+ㅣ=ㅚ, ㅜ+ㅓ=ㅝ, ㅜ+ㅔ=ㅞ, ㅜ+ㅣ=ㅟ, ㅡ+ㅣ=ㅢ
  1. Choseong là cần thiết. Điều đó có nghĩa là, nếu frkđược đưa ra, nghĩa là ㄹㄱㅏ, nó có thể thay đổi theo hai cách: ㄺㅏㄹ가. Sau đó, bạn phải chuyển đổi nó thành một cách đã chọn. Nếu jjjrjrđược đưa ra, đó là ㅓㅓㅓㄱㅓㄱ, hàng đầu không có bất cứ thứ gì có thể được chọn, nhưng thứ tư thể được chọn, vì vậy nó được đổi thành ㅓㅓㅓ걱.

Một ví dụ khác: 세계( tprP). Nó có thể được đổi thành 섹ㅖ( (ㅅㅔㄱ)(ㅖ)), nhưng vì đã chọn là cần thiết nên nó đã đổi thành 세계( (ㅅㅔ)(ㄱㅖ))

Ví dụ

đầu vào 1

안녕하세요

đầu ra 1

dkssudgktpdy

đầu vào 2

input 2

đầu ra 2

ㅑㅞㅕㅅ 2

đầu vào 3

힘ㄴㄴ

đầu ra 3

glass

đầu vào 4

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

đầu ra 4

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

đầu vào 5

dkssud, tprP!

đầu ra 5

안녕, 세계!

đầu vào 6

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

đầu ra 6

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

Mã ngắn nhất sẽ thắng. (tính bằng byte)

Quy tắc mới cho bạn thuận tiện

Bạn có thể loại bỏ các ký tự Akhông có đối tác trong bàn phím hai bộ. nên Aheuiđể Aㅗ뎌ㅑlà OK. Nhưng, nếu bạn đổi Aheuithành 모뎌ㅑ, bạn có thể nhận được -5 điểm, vì vậy bạn có thể kiếm được 5 byte.

Bạn có thể tách hai jungseongs (như để ㅗ+ㅏ). như rhkđể 고ㅏ, hoặc howđể ㅗㅐㅈ. Nhưng nếu bạn kết hợp nó (như rhkđể hoặc howđể ㅙㅈ), bạn có thể kiếm thêm -5 điểm.


Trong phần thứ tự jungseong, một trong những chữ cái bị thiếu. Tôi thấy 21 biểu tượng của Hàn Quốc, nhưng chỉ có 20 chữ cái. EDIT: Có vẻ như đang bỏ lỡ một thử nghiệm lsau mlcho biểu tượng Hàn Quốc .
Kevin Cruijssen

@KevinCruijssen chỉnh sửa. l cho.
LegenDUST

1
Đôi khi có thể có nhiều hơn một cách giải thích. Ví dụ, fjfaucó thể được hiểu là 럶ㅕhoặc 럴며. Làm thế nào để chúng ta giải quyết điều này?
Nick Kennedy

1
@LegenDUST Vâng, tôi không thể đọc một từ tiếng Hàn, vì vậy tôi sẽ phải giải thích cho bạn. ; p Như tprPtrong trường hợp thử nghiệm 5: điều này biến thành ㅅㅔㄱㅖ, nơi là một người được chọn, là một người đi rừng và là một jongseong. Vì vậy, không nên chuyển đổi thành 섷ㅖ(nhóm như (ㅅㅔㄱ)(ㅖ)) thay vì 세계(nhóm như (ㅅㅔ)(ㄱㅖ))? Trong một bình luận trước đó, bạn nêu nó là diễn giải bằng cách gõ, vì vậy tôi sẽ mong đợi ㅅㅔㄱchuyển thành . Hay là gõ tiếng Hàn từ phải sang trái thay vì trái sang phải?
Kevin Cruijssen

1
@KevinCruijssen tệp PDF từ Unicode.org. AC00 ( ) đến D7AF ( ).
LegenDUST

Câu trả lời:


6

Thạch , 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+⁽.[Ɗ$ẈṪ$ÞṚ¤ñỌ

Hãy thử trực tuyến!

Một chương trình đầy đủ lấy một chuỗi làm đối số của nó và trả về một chuỗi (được in ngầm). Điều này hoạt động trong ba lần: đầu tiên, nó chuyển đổi tất cả các ký tự tiếng Hàn thành danh sách các điểm mã cho các chữ cái Latinh. Sau đó, nó xác định và xây dựng các ký tự ghép tiếng Hàn. Cuối cùng, nó biến bất kỳ chữ Latinh đi lạc nào còn lại thành tương đương với tiếng Hàn. Lưu ý rằng các ký tự khác và các chữ cái Latinh không xuất hiện trong thông số (ví dụ A) được để riêng.

Nếu chuyển đổi sang chữ thường viết hoa bên ngoài spec là cần thiết, điều này có thể được thực hiện với chi phí thêm 10 byte .

Giải trình

Liên kết trợ giúp 1 : liên kết dyadic với các đối số x và y. x là danh sách các cặp tìm kiếm và thay thế danh sách con. y sẽ có mỗi danh sách con tìm kiếm được thay thế bằng danh sách con thay thế tương ứng

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

Trình trợ giúp liên kết 2 : Danh sách các ký tự / cặp ký tự Latinh theo thứ tự tương ứng với thứ tự Unicode của các ký tự tiếng Hàn

“Ȯ..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 : Danh sách các ký tự Latin được sử dụng cho Choseong, Jungseong và 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

Trình trợ giúp liên kết 4 : Danh sách các ký tự Latinh được liệt kê và sắp xếp theo thứ tự độ dài giảm dần

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

Liên kết chính : Monad lấy chuỗi Jelly làm đối số và trả về chuỗi Jelly đã dịch

Phần 1 : Chuyển đổi các khối hình thái thành các điểm mã Unicode của các ký tự Latinh tương ứng

Mục 1.1 : Lấy danh sách (các) ký tự Latinh cần thiết để tạo các khối

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)

Mục 1.2 : Tạo tất cả các kết hợp của các chữ cái này (19 × 21 × 28 = 11.172 kết hợp theo thứ tự từ vựng phù hợp)

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

Mục 1.3 : Ghép các điểm mã Unicode của các khối với danh sách các ký tự Latinh tương ứng và sử dụng các điểm này để dịch các khối hình thái trong chuỗi đầu vào

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

Phần 2 : Chuyển đổi các ký tự tiếng Hàn riêng lẻ trong đầu ra từ phần 1 sang các điểm mã tương đương với tiếng 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

Phần 3 : Dọn dẹp các ký tự chưa được dịch trong đầu ra từ phần 2 (hoạt động vì mọi thứ được dịch từ tiếng Hàn bây giờ sẽ nằm trong danh sách phụ và do đó có độ sâu 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

Phần 4 : Chuyển đổi các khối hình thái của các ký tự Latinh sang tiếng Hàn

Mục 4.1 : Nhận tất cả các kết hợp có thể có của Choseong và Jungseong

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

Mục 4.2 : Dán nhãn cho mỗi kết hợp với điểm mã Unicode cho khối hình thái cơ sở (nghĩa là không có 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]

Mục 4.3 : Thay thế các chuỗi ký tự Latinh này ở đầu ra từ phần 3 bằng các điểm mã Unicode của khối hình thái cơ sở

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

Mục 4.4: Xác định xem có một Jongseong như là một phần của mỗi khối hình thái không

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

Phần 5 : Xử lý các ký tự Latinh còn lại khớp với các ký tự tiếng Hàn nhưng không phải là một phần của khối hình thái

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
Đầu ra là sai: Khi tôi đặt , tôi đã loại trừ cor, nhưng nó đã cho cBor. Và nó không thay đổi cthành . canđã phải chuyển đổi thành ㅊ무, nhưng nó chuyển đổi thành c무. Và tôi cũng ngoại trừ những nhân vật lớn không xuất hiện trong thông số kỹ thuật sẽ bị khử, nhưng nó có thể ổn.
LegenDUST

@LegenDUST vấn đề c đã được sửa. Tôi đã sử dụng Anhư một trình giữ chỗ cho ký tự thứ hai của các ký tự đơn và vì một lý do nào đó, ký tự sau cxuất hiện dưới dạng a B. Chuyển đổi sang chữ thường của các chữ cái khác có thể được thực hiện, nhưng cảm thấy như một sự phức tạp không cần thiết đối với những gì đã là một thách thức khó khăn.
Nick Kennedy

Tôi hiểu điều này là khó khăn. Vì vậy, tôi đã thêm quy tắc mới: nếu bạn decapitalize, bạn có thể kiếm được 5 byte. Nhưng điều này là tốt.
LegenDUST

3

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

tfw bạn đã không biết điều đó 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):"")

Hãy thử trực tuyến!

547 nếu các ký tự bên ngoài bảng chữ cái và jamos Hàn Quốc có thể bị bỏ qua.

Được rồi tôi đã vật lộn quá lâu để viết cái này, nhưng cái này sẽ hoạt động. Không có jamo / âm tiết tiếng Hàn được sử dụng vì chúng quá đắt (3 byte mỗi lần sử dụng). Được sử dụng trong biểu thức chính quy để lưu 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

Ngôn ngữ Wolfram (Mathicala) , 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&

Hãy thử trực tuyến!

Hơi vô dụng

Để kiểm tra điều này trong Mathicala chỉ cần thay thế alphabetbằng Alphabet; tuy nhiên, TIO không hỗ trợ Wolfram Cloud nên tôi đã xác định Alphabet["Korean"]trong tiêu đề.

Trước tiên, chúng tôi phân tách tất cả các âm tiết Hangul sang bảng chữ cái Hangul, sau đó hoán đổi các ký tự Latin và Hangul, sau đó sắp xếp lại các âm tiết.


1
input 2Kết quả trường hợp thử nghiệm ㅑㅜㅔㅕㅅ 2thay vì ㅑㅞㅕㅅ 2trong TIO của bạn. Mặc dù điều tương tự cũng xảy ra trong giải pháp tôi đang thực hiện, vì cả hai đều là jungseong, và tôi có ấn tượng chỉ chọnong + jungseong + jongseong hoặc chọnong + jungseong + trống sẽ được kết hợp. Tôi yêu cầu OP xác minh tại sao ㅜㅔtrở thành .
Kevin Cruijssen

@KevinCruijssen (np) là một người đi rừng theo đúng nghĩa của nó
Nick Kennedy

1
Điều này dường như không hoạt động đúng cho hai phụ âm hoặc nguyên âm. Ví dụ: fnpfamột nhân vật duy nhất nhưng thay vào đó kết thúc là루ㅔㄹㅁ
Nick Kennedy

Sửa chữa trong tiến trình. Nó không nên chi phí quá nhiều.
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;}

Đầu ra với chữ in hoa ASDFGHJKLZXCVBNMkhông thay đổi, vì .toLowerCase()chi phí nhiều hơn phần thưởng -5.

Quay lại +7 byte dưới dạng sửa lỗi cho các ký tự không phải tiếng Hàn trên giá trị unicode 20.000 (cảm ơn @NickKennedy đã nhận thấy).

Hãy thử trực tuyến.

Giải trình:

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
chúng từ 44032 đến 55203. Bạn đã có vị trí bắt đầu được mã hóa. Kết thúc chỉ là44032 + 19×21×28 - 1
Nick Kennedy

Hoạt động tốt bây giờ. Nghĩ rằng tôi đã nâng đỡ bạn nhưng không, vì vậy bạn đến đây!
Nick Kennedy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.