Konvertiert zwischen koreanischer Zwei-Satz-Tastatur und QWERTY-Tastatur

14

Einführung

Es ist ein bisschen wie das DVORAK-Tastaturlayout , aber VIEL schwerer.

Lassen Sie uns zuerst über die koreanische Tastatur sprechen. Wie Sie in Wikipedia sehen können , gibt es einen Kor / Eng-Schlüssel, mit dem Sie zwischen koreanischen und englischen Schlüsselsätzen wechseln können.

Koreaner tippen manchmal falsch: Sie versuchen, auf einer QWERTY-Tastatur auf Koreanisch oder auf einer Tastatur mit zwei Sätzen auf Englisch zu schreiben.

Also, hier ist das Problem: Wenn Sie koreanische Zeichen in einer Tastatur mit zwei Tastensätzen eingegeben haben, konvertieren Sie diese in alphabetische Zeichen, die in einer QWERTY-Tastatur eingegeben wurden. Wenn Sie in qwerty eingegebene alphabetische Zeichen haben, ändern Sie diese in eine Tastatur mit zwei Sätzen.

Tastatur mit zwei Sätzen

Hier ist das Tastaturlayout mit zwei Sätzen:

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

und mit Shift-Taste:

ㅃㅉㄸㄲㅆㅛㅕㅑㅒㅖ

Nur die oberste Reihe ändert sich, die anderen nicht.

Über koreanische Schriftzeichen

wenn es hier endete, könnte es einfach sein, aber nein. Wenn Sie tippen

dkssud, tprP!

Die Ausgabe wird nicht wie folgt angezeigt:

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

aber so:

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

und es macht die Dinge viel schwieriger.

Koreanische Zeichen teilen sich in drei Teile: 'Choseong (Konsonant)', 'Jungseong (Vokal)' und 'Jongseong (Konsonant am Ende der Silbe: kann leer sein)', und Sie müssen es trennen.

Glücklicherweise gibt es dafür einen Weg.

Wie trenne ich mich?

Es gibt 19 Choseong, 21 Jungseong und 28 Jongseong (mit Leerzeichen) und 0xAC00 ist '가', das erste Zeichen der koreanischen Zeichen. Auf diese Weise können wir koreanische Zeichen in drei Teile unterteilen. Hier ist die Reihenfolge von jedem und seiner Position in Tastatur mit zwei Sätzen.

wähle eine Reihenfolge:

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

jungseong Bestellung:

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

jongseong Bestellung:

()ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ
()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

Lassen Sie uns sagen (unicode value of some character) - 0xAC00ist Korean_code, und der Index von Choseong, Jungseong, Jongseong ist Cho, Jung, Jong.

Dann Korean_codeist(Cho * 21 * 28) + Jung * 28 + Jong

Hier ist der JavaScript - Code , die koreanischen Zeichen trennen von dieser koreanischen Website, für Ihre Bequemlichkeit.

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

Im zusammengebauten Zustand

  1. Beachten Sie, dass , , , , , , ist eine Kombination aus anderen jungseongs.
ㅗ+ㅏ=ㅘ, ㅗ+ㅐ=ㅙ, ㅗ+ㅣ=ㅚ, ㅜ+ㅓ=ㅝ, ㅜ+ㅔ=ㅞ, ㅜ+ㅣ=ㅟ, ㅡ+ㅣ=ㅢ
  1. Choseong ist notwendig. Das heißt, wenn frkgegeben ist, was ist ㄹㄱㅏ, kann es sich auf zwei Arten ändern: ㄺㅏund ㄹ가. Dann müssen Sie es in einen Weg umwandeln, der Choseong hat. Wenn jjjrjrgegeben, ㅓㅓㅓㄱㅓㄱhaben führende s nichts, was gewählt werden kann, aber das vierte hat , was gewählt werden kann, also wird es in geändert ㅓㅓㅓ걱.

Ein weiteres Beispiel: 세계( tprP). Es kann in 섹ㅖ( (ㅅㅔㄱ)(ㅖ)) geändert werden , aber da Choseong erforderlich ist, wird es in 세계( (ㅅㅔ)(ㄱㅖ)) geändert.

Beispiele

Eingang 1

안녕하세요

Ausgang 1

dkssudgktpdy

Eingang 2

input 2

Ausgang 2

ㅑㅞㅕㅅ 2

eingang 3

힘ㄴㄴ

Ausgang 3

glass

eingang 4

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

Ausgang 4

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

eingang 5

dkssud, tprP!

Ausgang 5

안녕, 세계!

eingang 6

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

Ausgang 6

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

Kürzester Code gewinnt. (in Bytes)

Neue Regel für Sie Bequemlichkeit

Sie können Zeichen A, die nicht das Gegenstück zu einer Tastatur mit zwei Sätzen haben, verwerfen . so Aheuizu Aㅗ뎌ㅑist OK. Aber, wenn Sie ändern Aheuizu 모뎌ㅑkönnen Sie erhalten -5 Punkt, so dass Sie 5 Byte verdienen.

Sie können zwei jungseongs trennen (wie zu ㅗ+ㅏ). wie rhkauf 고ㅏoder howzu ㅗㅐㅈ. Aber wenn man es kombinieren (wie rhkauf oder howzu ㅙㅈ), können Sie zusätzliche -5 Punkte.

LegenDUST
quelle
In der Jungseong Order fehlt ein Buchstabe. Ich sehe 21 koreanische Symbole, aber nur 20 Buchstaben (-paare). BEARBEITEN: Scheint, eine Prüfung ldanach mlfür das koreanische Symbol zu fehlen .
Kevin Cruijssen
@KevinCruijssen bearbeitet. l für ㅣ.
LegenDUST
1
Manchmal kann es mehr als eine Interpretation geben. Beispielsweise fjfaukönnte als 럶ㅕoder interpretiert werden 럴며. Wie lösen wir das?
Nick Kennedy
1
@LegenDUST Nun, ich kann kein einziges koreanisches Wort lesen, daher muss ich mich an Ihre Erklärung halten. ; p Wie tprPim Testfall 5: Dies wandelt sich in ㅅㅔㄱㅖ, wo ein Choseong ist, ist ein Jungseong und ist ein Jongseong. So should't verwandeln diese in 섷ㅖ(gruppiert wie (ㅅㅔㄱ)(ㅖ)) statt 세계(gruppiert wie (ㅅㅔ)(ㄱㅖ))? In einem früheren Kommentar geben Sie an, dass es durch Tippen interpretiert wird, also würde ich erwarten ㅅㅔㄱ, dass es sich in verwandelt . Oder tippt Koreanisch von rechts nach links statt von links nach rechts?
Kevin Cruijssen
1
@ KevinCruijssen PDF-Datei von Unicode.org. AC00 ( ) bis D7AF ( ).
LegenDUST

Antworten:

6

Jelly , 296 264 Bytes

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

Probieren Sie es online!

Ein vollständiges Programm, das eine Zeichenfolge als Argument verwendet und eine Zeichenfolge zurückgibt (die implizit gedruckt wird). Dies funktioniert in drei Schritten: Zuerst werden alle koreanischen Zeichen in Codepunktlisten für die lateinischen Buchstaben konvertiert. Anschließend werden die zusammengesetzten koreanischen Zeichen identifiziert und erstellt. Schließlich werden alle verbleibenden lateinischen Streubuchstaben dem koreanischen Äquivalent zugeordnet. Beachten Sie, dass andere Zeichen und lateinische Buchstaben, die nicht in der Spezifikation enthalten sind (z. B. A), in Ruhe gelassen werden.

Wenn eine Konvertierung von Großbuchstaben außerhalb der Spezifikation in Kleinbuchstaben erforderlich ist, kann dies gegen einen Aufpreis von zusätzlichen 10 Byte erfolgen .

Erläuterung

Hilfslink 1 : dyadischer Link mit den Argumenten x und y. x ist eine Liste von Paaren von Unterlisten zum Suchen und Ersetzen. y lässt jede Such-Unterliste durch die entsprechende Ersetzungs-Unterliste ersetzen

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

Hilfslink 2 : Liste der lateinischen Zeichen / Zeichenpaare in der Reihenfolge, die der Unicode-Reihenfolge der koreanischen Zeichen entspricht

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

Hilfslink 3 : Listen lateinischer Zeichen, die für Choseong, Jungseong und Jongseong verwendet werden

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

Hilfslink 4 : Über Listen von lateinischen Zeichen, die in absteigender Reihenfolge der Länge aufgelistet und sortiert sind

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

Hauptlink : Monade, die eine Jelly-Zeichenfolge als Argument verwendet und die übersetzte Jelly-Zeichenfolge zurückgibt

Abschnitt 1 : Konvertieren Sie morphemische Blöcke in die Unicode-Codepunkte der entsprechenden lateinischen Zeichen

Abschnitt 1.1 : Liste der lateinischen Zeichen abrufen, die zum Erstellen der Blöcke erforderlich sind

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)

Abschnitt 1.2 : Erstellen Sie alle Kombinationen dieser Buchstaben (19 × 21 × 28 = 11.172 Kombinationen in der entsprechenden lexikalischen Reihenfolge)

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

Abschnitt 1.3 : Koppeln Sie die Unicode-Codepunkte der Blöcke mit der entsprechenden Liste lateinischer Zeichen und verwenden Sie diese, um die morphemischen Blöcke in der Eingabezeichenfolge zu übersetzen

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

Abschnitt 2 : Konvertieren Sie die einzelnen koreanischen Zeichen in der Ausgabe von Abschnitt 1 in die Codepunkte des lateinischen Äquivalents

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

Abschnitt 3 : Nicht übersetzte Zeichen in der Ausgabe von Abschnitt 2 aufräumen (funktioniert, weil alles, was aus dem Koreanischen übersetzt wurde, jetzt in einer Unterliste enthalten ist und die Tiefe 1 hat)

  ŒḊ?€  | 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

Abschnitt 4 : Konvertieren von Morphemblöcken aus lateinischen Zeichen in Koreanisch

Abschnitt 4.1 : Holen Sie sich alle möglichen Kombinationen von Choseong und Jungseong

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

Abschnitt 4.2 : Beschriften Sie jede Kombination mit dem Unicode-Codepunkt für den Basismorphemieblock (dh ohne 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]

Abschnitt 4.3 : Ersetzen Sie diese Zeichenfolgen aus lateinischen Zeichen in der Ausgabe von Abschnitt 3 durch die Unicode-Codepunkte des Basis-Morphemblocks

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

Abschnitt 4.4: Identifizieren Sie, ob es einen Jongseong als Teil jedes Morphemblocks gibt

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

Abschnitt 5 : Behandeln Sie verbleibende lateinische Zeichen, die mit koreanischen Zeichen übereinstimmen, jedoch nicht Teil eines Morphemuc-Blocks sind

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
Nick Kennedy
quelle
1
Ausgabe ist falsch: Wenn ich stelle , habe ich ausgenommen cor, aber es gab cBor. Und es ändert sich nicht czu . canmusste konvertiert in ㅊ무, aber es konvertiert in c무. Und ich habe auch große Zeichen, die nicht in der Spezifikation erscheinen, dekapitalisiert, aber es kann in Ordnung sein.
LegenDUST
@LegenDUST das c Problem ist behoben. Ich habe Aals Platzhalter für das zweite Zeichen eines einzelnen Zeichens verwendet, und aus irgendeinem Grund kam das folgende Zeichen cals B. Die Umstellung auf Kleinbuchstaben anderer Buchstaben könnte erfolgen, ist jedoch eine unnötige Komplikation für die ohnehin schwierige Aufgabe.
Nick Kennedy
Ich verstehe, das ist schwer. Also habe ich eine neue Regel hinzugefügt: Wenn Sie dekapitalisieren, können Sie 5 Bytes verdienen. Aber das ist in Ordnung.
LegenDUST
3

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

tfw das wusstest du nicht 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):"")

Probieren Sie es online!

547, wenn Zeichen außerhalb von Alphabeten und koreanischen Jamos ignoriert werden können.

Okay, ich hatte so lange Mühe, das zu schreiben, aber das sollte funktionieren. Es wird kein koreanisches Jamo / keine koreanische Silbe verwendet, da sie zu teuer sind (3 Bytes pro Verwendung). Wird im regulären Ausdruck zum Speichern von Bytes verwendet.

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
 )
Shieru Asakoto
quelle
2

Wolfram Language (Mathematica) , 405 401 400 Bytes

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&

Probieren Sie es online!

Leicht ungolfed

Um dies in Mathematica zu testen, ersetzen Sie einfach alphabetmit Alphabet; TIO unterstützt jedoch nicht die Wolfram Cloud, die ich definiert habeAlphabet["Korean"] im Header .

Wir zerlegen zuerst alle Hangul-Silben in das Hangul-Alphabet, tauschen dann die lateinischen und Hangul-Zeichen aus und setzen dann die Silben neu zusammen.

Lirtosiast
quelle
1
Testfallergebnisse input 2in ㅑㅜㅔㅕㅅ 2statt ㅑㅞㅕㅅ 2in Ihrem TIO. Obwohl das gleiche in der Lösung passiert, an der ich gearbeitet habe, da beide und jungseong sind, und ich den Eindruck hatte, dass nur Choseong + Jungseong + Jongseong oder Choseong + Jungseong + Leer kombiniert werden würden. Ich bat OP um Überprüfung, warum ㅜㅔwurde .
Kevin Cruijssen
@ KevinCruijssen ㅞ (np) ist ein Jungseong für sich
Nick Kennedy
1
Dies scheint für Konsonanten oder Vokale mit zwei Zeichen nicht richtig zu funktionieren. Zum Beispiel fnpfasollte es sich um ein einzelnes Zeichen handeln , das stattdessen als루ㅔㄹㅁ
Nick Kennedy
Fix in Bearbeitung. Es sollte nicht zu viel kosten.
Lirtosiast
2

Java 19, 1133 1126 1133 Bytes

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

Ausgaben mit Großbuchstaben ASDFGHJKLZXCVBNMunverändert, da .toLowerCase()mehr als der -5 Bonus kostet.

Back +7 Bytes als Bugfix für nicht-koreanische Zeichen über Unicode-Wert 20.000 (danke @NickKennedy für das Bemerken).

Probieren Sie es online aus.

Erläuterung:

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
Kevin Cruijssen
quelle
1
Sie sind von 44032 bis 55203. Sie haben bereits die Startposition codiert. Das Ende ist gerade44032 + 19×21×28 - 1
Nick Kennedy
Funktioniert jetzt gut. Ich dachte, ich hätte dich schon beleidigt, aber nicht, also los geht's!
Nick Kennedy