Преобразование между корейской клавиатурой с двумя наборами и клавиатурой qwerty


14

Вступление

Это немного похоже на раскладку DVORAK Keyboard , но НАМНОГО сложнее.

Давайте сначала поговорим о корейской клавиатуре. Как вы можете видеть в Википедии , есть ключ Kor / Eng для переключения между корейским и английским наборами ключей.

Корейцы иногда пишут неправильно: они пытаются писать на корейском языке с помощью qwerty-клавиатуры или на английском языке с помощью двухкомпонентной клавиатуры.

Итак, вот в чем проблема: если заданные корейские символы набраны на клавиатуре с двумя наборами, преобразуйте ее в буквенные символы, набранные на клавиатуре qwerty. Если даны буквенные символы, набранные в qwerty, измените его на клавиатуру с двумя наборами.

Клавиатура с двумя наборами

Вот две раскладки клавиатуры:

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

и с клавишей Shift:

ㅃㅉㄸㄲㅆㅛㅕㅑㅒㅖ

меняется только верхний ряд, а остальные нет.

О корейских персонажах

если это закончится здесь, это может быть легко, но нет. Когда вы печатаете

dkssud, tprP!

вывод не показан таким образом:

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

но так:

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

и это делает вещи намного сложнее.

Корейские символы разделены на три части: «Чосонг (согласный)», «Чунгсон (гласный)» и «Чонсонг (согласный в конце слога: может быть пустым)», и вы должны разделить его.

К счастью, есть способ сделать это.

Как отделить

Есть 19 Choseong, 21 Jungseong и 28 Jongseong (с пробелом), и 0xAC00 - это «가», первый символ корейских символов. Используя это, мы можем разделить корейские символы на три части. Вот порядок каждого и его положение в двух наборах клавиатуры.

выбрал порядок:

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

заказ jungseong:

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

заказ 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

Скажем Давайте (unicode value of some character) - 0xAC00есть Korean_code, и индекс ЧОСОН, юнсон, Jongseong есть Cho, Jung, Jong.

Тогда Korean_codeэто(Cho * 21 * 28) + Jung * 28 + Jong

Вот код JavaScript, который отделяет корейский символ от этого корейского сайта, для вашего удобства.

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

Когда собран

  1. Следует отметить , что , , , , , , представляет собой сочетание других jungseongs.
ㅗ+ㅏ=ㅘ, ㅗ+ㅐ=ㅙ, ㅗ+ㅣ=ㅚ, ㅜ+ㅓ=ㅝ, ㅜ+ㅔ=ㅞ, ㅜ+ㅣ=ㅟ, ㅡ+ㅣ=ㅢ
  1. Choseong необходимо. Это означает, что если frkдано, то есть ㄹㄱㅏ, оно может измениться двумя способами: ㄺㅏи ㄹ가. Затем вы должны преобразовать его в способ, который выбрал. Если jjjrjrдано, то есть ㅓㅓㅓㄱㅓㄱведущие s не имеют ничего, что можно выбрать, но четвертое имеет то, что можно выбрать, поэтому оно заменено на ㅓㅓㅓ걱.

Другой пример: 세계( tprP). Это может быть изменено на 섹ㅖ( (ㅅㅔㄱ)(ㅖ)), но так как необходимо выбратьong, оно заменено на 세계( (ㅅㅔ)(ㄱㅖ))

Примеры

вход 1

안녕하세요

выход 1

dkssudgktpdy

вход 2

input 2

выход 2

ㅑㅞㅕㅅ 2

вход 3

힘ㄴㄴ

выход 3

glass

вход 4

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

выход 4

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

вход 5

dkssud, tprP!

выход 5

안녕, 세계!

вход 6

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

выход 6

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

Самый короткий код выигрывает. (в байтах)

Новое правило для вашего удобства

Вы можете отклонить символы, подобные Aкоторым не имеют своего аналога в двух наборах клавиатуры. так что все Aheuiв Aㅗ뎌ㅑпорядке. Но если вы измените Aheuiна 모뎌ㅑ, вы можете получить -5 баллов, то есть вы можете заработать 5 байтов.

Вы можете выделить два jungseongs (как в ㅗ+ㅏ). как rhkк 고ㅏ, или howк ㅗㅐㅈ. Но если объединить его (например , rhkв или howна ㅙㅈ), вы можете заработать дополнительные -5 баллов.


В разделе заказа jungseong одна из букв отсутствует. Я вижу 21 корейский символ, но только 20 букв (-пара). РЕДАКТИРОВАТЬ: Кажется, пропускает испытание lпосле mlкорейского символа .
Кевин Круйссен

@KevinCruijssen отредактировано. Я за ㅣ.
LegenDUST

1
Иногда может быть несколько интерпретаций. Например, fjfauможно интерпретировать как 럶ㅕили 럴며. Как мы решаем это?
Ник Кеннеди

1
@ LegenDUST Ну, я не могу прочитать ни слова по-корейски, поэтому я должен пойти с вашим объяснением. ; p Как и tprPв тестовом примере 5: он трансформируется в ㅅㅔㄱㅖ, где есть selectedong, jungseong и jongseong. Так не должно ли это преобразоваться в 섷ㅖ(сгруппированные как (ㅅㅔㄱ)(ㅖ)) вместо 세계(сгруппированные как (ㅅㅔ)(ㄱㅖ))? В более раннем комментарии вы утверждаете, что он интерпретируется путем ввода текста, поэтому я ожидал ㅅㅔㄱбы преобразоваться в . Или корейский печатает справа налево, а не слева направо?
Кевин Круйссен

1
@KevinCruijssen PDF-файл с Unicode.org. AC00 ( ) - D7AF ( ).
LegenDUST

Ответы:


6

Желе , 296 264 байта

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

Попробуйте онлайн!

Полная программа, которая принимает строку в качестве аргумента и возвращает строку (которая неявно печатается). Это работает в три этапа: сначала он преобразует все корейские символы в списки кодовых точек для латинских букв. Затем он идентифицирует и создает составные корейские символы. Наконец, он превращает любые оставшиеся латинские буквы в корейский эквивалент. Обратите внимание, что другие символы и латинские буквы, которые не появляются в спецификации (например A), остаются одни.

Если необходимо преобразовать заглавные буквы в нижний регистр вне спецификации, это можно сделать за счет дополнительных 10 байтов .

объяснение

Вспомогательная ссылка 1 : двоичная ссылка с аргументами x и y. x - это список пар поиска и замены подсписков. у будет заменен каждый подсписок поиска на соответствующий подсписок замены

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

Вспомогательная ссылка 2 : Список латинских пар символов / символов в порядке, соответствующем порядку Unicode корейских символов

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

Вспомогательная ссылка 3 : Списки латинских символов, используемых для Чосонга, Чонсонга и Чонсона

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

Вспомогательная ссылка 4 : перечисленные выше списки латинских символов в порядке убывания длины

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

Основная ссылка : Монада, которая принимает строку Jelly в качестве аргумента и возвращает переведенную строку Jelly

Раздел 1. Преобразование морфемных блоков в кодовые точки Unicode соответствующих латинских символов

Раздел 1.1 : Получить список латинских символов, необходимых для создания блоков

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)

Раздел 1.2 : Создайте все комбинации этих букв (19 × 21 × 28 = 11 172 комбинации в соответствующем лексическом порядке)

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

Раздел 1.3 : Соедините кодовые точки Unicode блоков с соответствующим списком латинских символов и используйте их для перевода морфемных блоков во входной строке

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

Раздел 2. Преобразование отдельных корейских символов в выводе из раздела 1 в кодовые точки латинского эквивалента

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

Раздел 3 : привести в порядок непереведенные символы в выводе из раздела 2 (работает, потому что все, что переведено с корейского языка, теперь будет в подсписке и будет иметь глубину 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

Раздел 4. Преобразование морфемных блоков латинских букв в корейский.

Раздел 4.1 : Получить все возможные комбинации Choseong и Jungseong

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

Раздел 4.2 : Маркируйте каждую комбинацию с помощью кодовой точки Unicode для основного морфемного блока (т.е. без 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]

Раздел 4.3 : Заменить эти строки латинских символов в выводе из раздела 3 на кодовые точки Unicode базового морфемного блока

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

Раздел 4.4: Определите, есть ли Jongseong как часть каждого морфемного блока

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

Раздел 5 : Обработка оставшихся латинских символов, которые соответствуют корейским, но не являются частью блока 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
Вывод неверный: когда я ставил , я исключал cor, но это давало cBor. И это не меняется cна . canдолжен был быть преобразован в ㅊ무, но он преобразован в c무. И я также исключил, что большие символы, которые не указаны в спецификации, будут декапитализированы, но это может быть хорошо.
LegenDUST

@ LegenDUST проблема с исправлена. Я использовал Aв качестве заполнителя для второго символа отдельных символов, и по какой-то причине тот, что после, cполучился как B. Преобразование других букв в нижний регистр может быть выполнено, но кажется ненужным осложнением того, что уже является сложной задачей.
Ник Кеннеди

Я понимаю, что это сложно. Поэтому я добавил новое правило: если вы декапитализируете, вы можете заработать 5 байт. Но это нормально.
LegenDUST

3

JavaScript (Node.js) , 587 582 575 569 557 554 550 549 байт

ты не знал этого 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):"")

Попробуйте онлайн!

547, если символы за пределами алфавитов и корейских джамо могут быть проигнорированы.

Хорошо, я так долго боролся, чтобы написать это, но это должно сработать. Корейский джамо / слог не используется, потому что они слишком дороги (3 байта за использование). Используется в регулярном выражении для сохранения байтов.

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 Language (Mathematica) , 405 401 400 байт

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&

Попробуйте онлайн!

Слегка разгульный

Чтобы проверить это в Mathematica, просто замените alphabetна Alphabet; однако TIO не поддерживает Wolfram Cloud, поэтому я определил Alphabet["Korean"]в шапке.

Сначала мы разлагаем все слоги хангыль на алфавит хангул, затем меняем символы латинского и хангульского языков, а затем восстанавливаем слоги.


1
input 2Результат теста ㅑㅜㅔㅕㅅ 2вместо ㅑㅞㅕㅅ 2вашего TIO. Хотя то же самое происходит с решением, над которым я работал, поскольку оба и jungseong, и у меня сложилось впечатление, что будут выбраны только комбинацияong + jungseong + jongseong или selectedong + jungseong + empty. Я спросил ОП для проверки, почему ㅜㅔстал .
Кевин Круйссен

@KevinCruijssen ㅞ (np) сам по себе является джунгсон
Ник Кеннеди

1
Это, кажется, не работает должным образом для двух согласных или гласных символов. Например, fnpfaдолжен быть один символ, но вместо этого заканчивается как루ㅔㄹㅁ
Ник Кеннеди

Исправление в процессе. Это не должно стоить слишком дорого.
lirtosiast

2

Ява 19, 1133 1126 1133 байта

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

Выводы с заглавными буквами не ASDFGHJKLZXCVBNMизменяются, так как .toLowerCase()стоит больше, чем бонус -5.

Возвращение +7 байт в качестве исправления ошибки для некорейских символов со значением, превышающим юникод 20 000 (спасибо @NickKennedy за то, что заметил).

Попробуйте онлайн.

Объяснение:

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 по 55203. У вас уже есть закодированное начальное местоположение. Конец просто44032 + 19×21×28 - 1
Ник Кеннеди

Хорошо работает сейчас. Думаю, я уже проголосовал против тебя, но не сделал, так что вот и все!
Ник Кеннеди
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.