Converti tra tastiera coreana a due set e tastiera qwerty


14

introduzione

È un po 'come il layout della tastiera DVORAK , ma MOLTO più difficile.

Parliamo prima della tastiera coreana. Come puoi vedere in Wikipedia , c'è una chiave Kor / Eng per cambiare tra le chiavi coreane e inglesi.

I coreani a volte digitano male: tentano di scrivere in coreano su una tastiera qwerty o in inglese su una tastiera a due set.

Quindi, ecco il problema: se dati caratteri coreani digitati in tastiera a due set, convertilo in caratteri alfabetici digitati in tastiera qwerty. Se vengono indicati i caratteri alfabetici digitati in qwerty, cambiarlo in tastiera a due set.

Tastiera a due set

Ecco il layout della tastiera a due set:

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

e con il tasto Maiusc:

ㅃㅉㄸㄲㅆㅛㅕㅑㅒㅖ

cambia solo la riga superiore mentre le altre no.

Informazioni sui personaggi coreani

se finisse qui, potrebbe essere facile, ma no. Quando si digita

dkssud, tprP!

l'output non viene mostrato in questo modo:

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

ma in questo modo:

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

e rende le cose molto più difficili.

I personaggi coreani si separano in tre parti: "Choseong (consonante)", "Jungseong (vocale)" e "Jongseong (consonante alla fine della sillaba: può essere vuoto)", e devi separarlo.

Fortunatamente, c'è un modo per farlo.

Come separare

Ci sono 19 Choseong, 21 Jungseong e 28 Jongseong (con spazio vuoto), e 0xAC00 è '가', primo personaggio dei personaggi coreani. Usando questo, possiamo separare i caratteri coreani in tre parti. Ecco l'ordine di ciascuno e la sua posizione nella tastiera a due set.

ordine scelto:

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

ordine jungseong:

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

ordine 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

Diciamo di Let (unicode value of some character) - 0xAC00è Korean_code, e l'indice di Choseong, jungseong, Jongseong è Cho, Jung, Jong.

Quindi lo Korean_codeè(Cho * 21 * 28) + Jung * 28 + Jong

Ecco il codice javascript che separa il carattere coreano da questo sito Web coreano, per comodità.

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

Quando assemblato

  1. Si noti che , , , , , , è una combinazione di altri jungseongs.
ㅗ+ㅏ=ㅘ, ㅗ+ㅐ=ㅙ, ㅗ+ㅣ=ㅚ, ㅜ+ㅓ=ㅝ, ㅜ+ㅔ=ㅞ, ㅜ+ㅣ=ㅟ, ㅡ+ㅣ=ㅢ
  1. Choseong è necessario. Ciò significa che, se frkviene dato, ovvero ㄹㄱㅏ, può cambiare in due modi: ㄺㅏe ㄹ가. Quindi, devi convertirlo in un modo che ha sceltoong. Se jjjrjrdato, che è ㅓㅓㅓㄱㅓㄱ, leader s non hanno tutto ciò che può essere CHOSEONG, ma il quarto ha che può essere CHOSEONG, quindi è cambiato in ㅓㅓㅓ걱.

Un altro esempio: 세계( tprP). Può essere modificato in 섹ㅖ( (ㅅㅔㄱ)(ㅖ)), ma poiché è necessario scegliereong, viene modificato in 세계( (ㅅㅔ)(ㄱㅖ))

Esempi

input 1

안녕하세요

uscita 1

dkssudgktpdy

ingresso 2

input 2

uscita 2

ㅑㅞㅕㅅ 2

input 3

힘ㄴㄴ

uscita 3

glass

ingresso 4

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

uscita 4

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

input 5

dkssud, tprP!

uscita 5

안녕, 세계!

input 6

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

uscita 6

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

Il codice più corto vince. (in byte)

Nuova regola per la tua convenienza

Puoi eliminare caratteri come quelli Ache non hanno la loro controparte in una tastiera a due set. in modo Aheuida Aㅗ뎌ㅑè OK. Ma, se cambi Aheuia 모뎌ㅑ, puoi ottenere -5 punti, quindi puoi guadagnare 5 byte.

Puoi separare due jungseong (come a ㅗ+ㅏ). come rhka 고ㅏ, o howa ㅗㅐㅈ. Ma se lo combini (come rhka o howa ㅙㅈ), puoi guadagnare ulteriori 5 punti.


Nella sezione ordine jungseong manca una delle lettere. Vedo 21 simboli coreani, ma solo 20 lettere (-pair) s. EDIT: sembra mancare una prova ldopo mlper il simbolo coreano .
Kevin Cruijssen,

@KevinCruijssen modificato. l per ㅣ.
LegenDUST,

1
A volte può esserci più di un'interpretazione. Ad esempio, fjfaupotrebbe essere interpretato come 럶ㅕo 럴며. Come lo risolviamo?
Nick Kennedy,

1
@LegenDUST Beh, non riesco a leggere una sola parola coreano, quindi dovrò seguire la tua spiegazione. ; p Come tprPnel caso di test 5: questo si trasforma in ㅅㅔㄱㅖ, dove è scelto, è un jungseong ed è un jongseong. Quindi questo non dovrebbe trasformarsi in 섷ㅖ(raggruppato come (ㅅㅔㄱ)(ㅖ)) invece di 세계(raggruppato come (ㅅㅔ)(ㄱㅖ))? In un commento precedente affermi che è interpretare digitando, quindi mi aspetto ㅅㅔㄱdi trasformarmi in . O sta scrivendo il coreano da destra a sinistra anziché da sinistra a destra?
Kevin Cruijssen,

1
@KevinCruijssen file PDF da Unicode.org. Da AC00 ( ) a D7AF ( ).
LegenDUST,

Risposte:


6

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

Provalo online!

Un programma completo che accetta una stringa come argomento e restituisce una stringa (che viene implicitamente stampata). Funziona in tre passaggi: prima converte tutti i caratteri coreani in elenchi di punti di codice per le lettere latine. Quindi identifica e costruisce i caratteri coreani composti. Infine, trasforma le lettere latine vaganti rimaste nell'equivalente coreano. Si noti che altri caratteri e lettere latine che non compaiono nelle specifiche (ad es. A) Vengono lasciati soli.

Se è necessaria la conversione in lettere minuscole al di fuori delle specifiche, questo può essere fatto al costo di ulteriori 10 byte .

Spiegazione

Link helper 1 : link diadico con argomenti xey. x è un elenco di coppie di ricerca e sostituisce elenchi secondari. y sostituirà ciascun elenco secondario di ricerca con il corrispondente elenco secondario di sostituzione

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

Collegamento helper 2 : elenco di caratteri latini / coppie di caratteri nell'ordine corrispondente all'ordine Unicode dei caratteri coreani

“Ȯ..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 : Elenchi di caratteri latini usati per Choseong, Jungseong e 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

Link helper 4 : sopra gli elenchi di caratteri latini elencati e ordinati in ordine decrescente di lunghezza

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

Link principale : Monade che accetta una stringa Jelly come argomento e restituisce la stringa Jelly tradotta

Sezione 1 : Converti i blocchi morfici nei punti di codice Unicode dei corrispondenti caratteri latini

Sezione 1.1 : Ottieni l'elenco dei caratteri latini necessari per realizzare i blocchi

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)

Sezione 1.2 : Crea tutte le combinazioni di queste lettere (19 × 21 × 28 = 11.172 combinazioni nell'ordine lessicale appropriato)

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

Sezione 1.3 : Associare i punti di codice Unicode dei blocchi con l'elenco corrispondente di caratteri latini e utilizzarli per tradurre i blocchi morfici nella stringa di 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

Sezione 2 : Converti i singoli caratteri coreani nell'output dalla sezione 1 ai punti di codice dell'equivalente latino

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

Sezione 3 : Riordina i caratteri non tradotti nell'output della sezione 2 (funziona perché qualsiasi cosa tradotta dal coreano sarà ora in un elenco secondario e quindi avrà profondità 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

Sezione 4 : Convertire blocchi morfici di caratteri latini in coreano

Sezione 4.1 : Ottieni tutte le possibili combinazioni di Choseong e Jungseong

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

Sezione 4.2 : Etichettare ogni combinazione con il punto di codice Unicode per il blocco morfico di base (cioè senza 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]

Sezione 4.3 : Sostituisci queste stringhe di caratteri latini nell'output della sezione 3 con i punti di codice Unicode del blocco morfico di base

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

Sezione 4.4: Identificare se esiste un Jongseong come parte di ciascun blocco morfico

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

Sezione 5 : Gestisci i caratteri latini rimanenti che corrispondono a quelli coreani ma che non fanno parte di un blocco 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
L'output è sbagliato: quando l'ho messo , ho escluso cor, ma ha dato cBor. E non cambia cin . canha dovuto convertirsi in ㅊ무, ma si è convertito in c무. E ho anche escluso che personaggi di grandi dimensioni che non compaiono nelle specifiche sarebbero decapitalizzati, ma può andare bene.
LegenDUST,

@LegenDUST il problema c è stato risolto. Ho usato Acome segnaposto per il secondo personaggio di singoli personaggi, e per qualche motivo quello successivo cstava uscendo come B. La conversione in lettere minuscole di altre lettere potrebbe essere fatta, ma sembra una complicazione inutile per quella che è già una sfida difficile.
Nick Kennedy

Capisco che è difficile. Quindi ho aggiunto una nuova regola: se decapitalizzi, puoi guadagnare 5 byte. Ma va bene.
LegenDUST,

3

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

perché non lo sapevi 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):"")

Provalo online!

547 se i caratteri al di fuori degli alfabeti e dei jamos coreani possono essere ignorati.

Ok, ho lottato per così tanto tempo per scrivere questo, ma dovrebbe funzionare. Nessun jamo / sillaba coreano viene utilizzato perché sono troppo costosi (3 byte per uso). Utilizzato nell'espressione regolare per salvare 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

Wolfram Language (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&

Provalo online!

Leggermente ungolfed

Per provare questo in Mathematica basta sostituire alphabetcon Alphabet; tuttavia, TIO non supporta Wolfram Cloud, quindi ho definito Alphabet["Korean"]nell'intestazione.

Decomponiamo prima tutte le sillabe Hangul con l'alfabeto Hangul, quindi scambiamo i caratteri latini e Hangul, quindi ricomporre le sillabe.


1
input 2Risultati del test case ㅑㅜㅔㅕㅅ 2invece che ㅑㅞㅕㅅ 2nel TIO. Sebbene lo stesso accada nella soluzione a cui stavo lavorando, poiché entrambi e sono jungseong, e io avevo l'impressione che solo combinati scegliereong + jungseong + jongseong o sceltoong + jungseong + vuoto. Ho chiesto a OP di verificare perché è ㅜㅔdiventato .
Kevin Cruijssen,

@KevinCruijssen ㅞ (np) è un jungseong a sé stante
Nick Kennedy,

1
Questo non sembra funzionare correttamente per consonanti o vocali di due personaggi. Ad esempio fnpfadovrebbe essere un singolo personaggio, ma invece finisce come루ㅔㄹㅁ
Nick Kennedy

Correzione in corso. Non dovrebbe costare troppo.
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 con lettere maiuscole ASDFGHJKLZXCVBNMinvariate, dal momento che .toLowerCase()costa più del bonus di -5.

Indietro +7 byte come correzione di bug per caratteri non coreani oltre il valore unicode 20.000 (grazie a @NickKennedy per averlo notato).

Provalo online.

Spiegazione:

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
vanno da 44032 a 55203. La posizione di partenza è già codificata. La fine è solo44032 + 19×21×28 - 1
Nick Kennedy

Funziona bene ora. Pensavo di averti già votato ma non l'ho fatto, quindi eccoti qui!
Nick Kennedy,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.