Перетворення між корейською двоступінчастою клавіатурою та клавіатурою qwerty


14

Вступ

Це дещо схоже на розкладку клавіатури DVORAK , але МНОГО складніше.

Давайте спочатку поговоримо про корейську клавіатуру. Як ви бачите у Вікіпедії , для корекції між корейською та англійською клавішами є клавіша Kor / Eng.

Колись корейці вводять неправильно: вони намагаються писати по-корейськи на клавіатурі qwerty або англійською мовою на двонабірній клавіатурі.

Отже, ось проблема: якщо задано корейські символи, введені на двох клавіатурах, перетворіть їх на алфавітні символи, набрані на клавіатурі qwerty. Якщо введено алфавітні символи, введені qwerty, змініть його на двонабірну клавіатуру.

Клавіатура з двома наборами

Ось розкладка клавіатури з двома наборами:

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

і з клавішею Shift:

ㅃㅉㄸㄲㅆㅛㅕㅑㅒㅖ

просто змінюється верхній ряд, а інші - ні.

Про корейських персонажів

якби це закінчилося тут, це може бути легко, але ні. Коли ви вводите текст

dkssud, tprP!

вихід не відображається таким чином:

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

але таким чином:

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

і це значно ускладнює.

Корейські символи розділяються на три частини: "Choseong (приголосний)", "Jungseong (голосний)" та "Jongseong (приголосний у кінці складу: може бути порожнім)", і ви повинні розділити його.

На щастя, є спосіб це зробити.

Як відокремити

Є 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. Чосонг необхідний. Це означає, що якщо frkце дано, що є ㄹㄱㅏ, воно може змінитися двома способами: ㄺㅏі ㄹ가. Тоді вам доведеться перетворити його у спосіб, який обрав довгі. Якщо jjjrjrдано, що є ㅓㅓㅓㄱㅓㄱ, то у ведучих s немає нічого, що можна вибрати довгі, але четверте , що може бути вибранеong, тож воно буде змінено на ㅓㅓㅓ걱.

Інший приклад: 세계( tprP). Його можна змінити на 섹ㅖ( (ㅅㅔㄱ)(ㅖ)), але, оскільки вибрав необхідний, він зміниться на 세계( (ㅅㅔ)(ㄱㅖ))

Приклади

вхід 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 балів.


У розділі замовлення джунгсей одна з букв відсутня. Я бачу 21 корейських символів, але лише 20 літер (-пара). EDIT: Здається пропускати випробування того lпісля mlдля корейського символу .
Кевін Кройсейсен

@KevinCruijssen відредаговано. l для ㅣ.
LegenDUST

1
Іноді може бути більше одного тлумачення. Наприклад, fjfauможна інтерпретувати як 럶ㅕабо 럴며. Як ми вирішуємо це?
Нік Кеннеді

1
@LegenDUST Ну, я не можу прочитати жодного слова корейською мовою, тому мені доведеться піти з вашими поясненнями. ; p Що стосується tprPтестового випадку 5: це перетворюється на ㅅㅔㄱㅖ, де є вибранг, є джунгсон і є джонсенг. Так чи не повинно це перетворюватися на 섷ㅖ(згруповане подібне (ㅅㅔㄱ)(ㅖ)) замість 세계(згруповане як (ㅅㅔ)(ㄱㅖ))? У попередньому коментарі ви заявляєте, що це інтерпретується введенням тексту, тому я б розраховував ㅅㅔㄱперетворитися на . Або корейська набирає справа наліво, а не зліва направо?
Кевін Круїссен

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 - це список пар списків пошуку та заміни. y буде замінено кожен підпис під пошуковим записом на відповідний підпис

Ẏ      | 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 : Списки латинських символів, які використовуються для Choseong, Jungseong та 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

Посилання помічника 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 : Отримайте всі можливі комбінації Чхосеонг та Юнгсейн

¢    | 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: Визначте, чи є Чженсон в складі кожного морфемічного блоку

                                        Ʋ | 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 : Обробіть інші латинські символи, які відповідають корейським, але не є частиною блоку морфемуків

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 проблема c виправлена. Я використовував Aяк заповнювач для другого символу одиноких символів, і чомусь той, що cз'явився, виходив як а B. Перетворення в малі регістри інших букв може бути здійснено, але це вважається зайвим ускладненням того, що вже є складним викликом.
Нік Кеннеді

Я розумію, що це важко. Тому я додав нове правило: якщо декапіталізувати, ви можете заробити 5 байт. Але це добре.
LegenDUST

3

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

tfw ти цього не знав 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

Мова Вольфрама (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 не підтримує Cloudram Cloud, тому я визначив Alphabet["Korean"]у заголовку.

Спочатку ми розкладаємо всі склади Хангула на алфавіт Хангул, потім підміняємо символи латини та Хангула, потім рекомпонуємо склади.


1
Тестовий випадок input 2призводить ㅑㅜㅔㅕㅅ 2замість ㅑㅞㅕㅅ 2вашої TIO. Хоча те саме відбувається в рішенні, над яким я працював, оскільки обидва і є jungseong, і я був під враженням, що поєднуються лише izaong + jungseong + jongseong або izaong + jungseong + empty. Я попросив ОП для перевірки, чому це ㅜㅔстало .
Кевін Круїссен

@KevinCruijssen ㅞ (np) - власне джунгсон
Нік Кеннеді

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

Виправлення в процесі виконання. Це не повинно коштувати занадто дорого.
lirtosiast

2

Java 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 байт як виправлення помилок для некорейських символів вище значення unicode 20000 (спасибі @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.