แปลงระหว่างแป้นพิมพ์สองชุดเกาหลีและแป้นพิมพ์แบบ qwerty


14

บทนำ

มันค่อนข้างเหมือนกับรูปแบบแป้นพิมพ์ DVORAKแต่ยากกว่ามาก

มาพูดถึงคีย์บอร์ดเกาหลีกันก่อนดีกว่า อย่างที่คุณเห็นในWikipediaมีคีย์ Kor / Eng เพื่อเปลี่ยนระหว่างชุดคีย์เกาหลีและอังกฤษ

บางครั้งคนเกาหลีพิมพ์ผิด: พวกเขาพยายามเขียนเป็นภาษาเกาหลีบนแป้นพิมพ์แบบ qwerty หรือภาษาอังกฤษบนแป้นพิมพ์สองชุด

ดังนั้นนี่คือปัญหา: หากมีตัวอักษรภาษาเกาหลีพิมพ์อยู่ในแป้นพิมพ์สองชุดให้แปลงเป็นอักขระตัวอักษรที่พิมพ์ด้วยแป้นพิมพ์แบบ qwerty หากตัวอักษรที่กำหนดให้พิมพ์เป็น qwerty ให้เปลี่ยนเป็นคีย์บอร์ดสองชุด

คีย์บอร์ดสองชุด

นี่คือรูปแบบแป้นพิมพ์สองชุด:

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

และด้วยปุ่ม Shift:

ㅃㅉㄸㄲㅆㅛㅕㅑㅒㅖ

การเปลี่ยนแปลงแถวบนสุดในขณะที่คนอื่นไม่ทำ

เกี่ยวกับตัวละครเกาหลี

ถ้ามันจบลงที่นี่มันอาจจะง่าย แต่ไม่ใช่ เมื่อคุณพิมพ์

dkssud, tprP!

เอาท์พุทไม่ได้แสดงในลักษณะนี้:

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

แต่ด้วยวิธีนี้:

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

และทำให้สิ่งต่าง ๆ ยากขึ้นมาก

ตัวอักษรเกาหลีแยกออกเป็นสามส่วน: 'Choseong (พยัญชนะ)', 'Jungseong (Vowel)' และ '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

สั่งจองซอง:

ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ
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และดัชนีของ Choseong, Jungseong, Jongseong คือCho, ,JungJong

จากนั้นKorean_codeเป็น(Cho * 21 * 28) + Jung * 28 + Jong

นี่คือรหัสจาวาสคริปต์ที่แยกตัวอักษรเกาหลีออกจากเว็บไซต์เกาหลีนี้เพื่อความสะดวกของคุณ

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 ไม่ได้มีอะไรที่สามารถ CHOSEONG แต่ที่สี่มีที่สามารถ CHOSEONG ㅓㅓㅓ걱จึงเปลี่ยนเป็น

ตัวอย่างอื่น: 세계( 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 ตัวอักษร (-pair) s แก้ไข: ดูเหมือนจะหายไปทดลองlหลังจากสัญลักษณ์เกาหลีml
Kevin Cruijssen

@KevinCruijssen แก้ไขแล้ว l สำหรับㅣ
LegenDUST

1
บางครั้งอาจมีการตีความมากกว่าหนึ่งครั้ง ยกตัวอย่างเช่นfjfauอาจจะตีความว่าเป็นหรือ럶ㅕ 럴며เราจะแก้ไขปัญหานี้อย่างไร
Nick Kennedy

1
@LegenDUST ดีฉันไม่สามารถอ่านคำภาษาเกาหลีคำเดียวดังนั้นฉันจะต้องไปกับคำอธิบายของคุณ ; สำหรับtprPการทดสอบในกรณีที่ 5: สิ่งนี้เปลี่ยนเป็นㅅㅔㄱㅖที่เลือกคืออะไรคือจองซองและจองซอง ดังนั้นสิ่งนี้ไม่ควรเปลี่ยนเป็น섷ㅖ(จัดกลุ่มเหมือน(ㅅㅔㄱ)(ㅖ)) แทนที่จะเป็น세계(จัดกลุ่มชอบ(ㅅㅔ)(ㄱㅖ)) ใช่ไหม ในความคิดเห็นก่อนหน้านี้คุณรัฐมันเป็นตีความโดยพิมพ์ดังนั้นผมจะคาดหวังที่จะกลายเป็นㅅㅔㄱ หรือพิมพ์ภาษาเกาหลีจากขวาไปซ้ายแทนซ้ายไปขวา
Kevin Cruijssen

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 : ลิงค์ dyadic พร้อมอาร์กิวเมนต์ 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

ลิงก์หลัก : Monad ที่ใช้สตริง Jelly เป็นอาร์กิวเมนต์และส่งคืนสตริง Jelly แปล

ส่วนที่ 1 : แปลงบล็อค morphemic เป็น Unicode codepoints ของอักขระละตินที่เกี่ยวข้อง

ส่วนที่ 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 ของบล็อกกับรายการอักขระละตินที่ตรงกันและใช้สิ่งเหล่านี้เพื่อแปลบล็อก morphemic ในสตริงอินพุต

       Ʋ   | 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 : แปลงบล็อค morphemic ของอักขระละตินเป็นภาษาเกาหลี

ส่วนที่ 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 สำหรับบล็อก morphemic พื้นฐาน (เช่นที่ไม่มี 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 ของบล็อก morphemic พื้นฐาน

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

ส่วนที่ 4.4: ระบุว่ามี Jongseong เป็นส่วนหนึ่งของแต่ละบล็อก morphemic

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

@ ได้รับอนุญาตปัญหา c ได้รับการแก้ไข ผมใช้Aเป็นตัวยึดสำหรับตัวละครที่สองของตัวละครเดียวและด้วยเหตุผลบางอย่างหนึ่งหลังจากที่ออกมาเป็นc Bการแปลงเป็นตัวอักษรตัวเล็กสามารถทำได้ แต่ให้ความรู้สึกเหมือนการแทรกซ้อนที่ไม่จำเป็นสำหรับสิ่งที่ท้าทายอยู่แล้ว
Nick Kennedy

ฉันเข้าใจว่ามันยาก ดังนั้นฉันจึงเพิ่มกฎใหม่: ถ้าคุณทำการย่อส่วนคุณสามารถสร้างรายได้ 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 ถ้าตัวละครนอกตัวอักษรและ jamos เกาหลีสามารถละเว้น

โอเคฉันพยายามอย่างมากที่จะเขียนสิ่งนี้ แต่มันควรจะได้ผล ไม่มีการใช้ jamo / พยางค์เกาหลีเนื่องจากแพงเกินไป (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 (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&

ลองออนไลน์!

ungolfed เล็กน้อย

เพื่อทดสอบใน Mathematica เพียงแทนที่alphabetด้วยAlphabet; อย่างไรก็ตาม TIO ไม่สนับสนุน Wolfram Cloud ดังนั้นฉันจึงกำหนดไว้Alphabet["Korean"]ในส่วนหัว

อันดับแรกเราจะแยกพยางค์ภาษาอังกูลทั้งหมดเป็นตัวอักษรอังกูลจากนั้นสลับอักขระภาษาละตินและภาษาอังกูลจากนั้นเปลี่ยนพยางค์อีกครั้ง


1
input 2ผลการทดสอบในㅑㅜㅔㅕㅅ 2แทนที่จะเป็นㅑㅞㅕㅅ 2TIO ของคุณ แม้ว่าสิ่งเดียวกันจะเกิดขึ้นในวิธีการแก้ปัญหาที่ฉันกำลังทำงานอยู่เนื่องจากทั้งสองและเป็นจองซองและฉันก็อยู่ภายใต้ความประทับใจที่เลือกเท่านั้น ฉันถาม OP สำหรับการตรวจสอบว่าทำไมกลายเป็นㅜㅔ
Kevin Cruijssen

@KevinCruijssen ㅞ (np) เป็น jungseong ในสิทธิ์ของตัวเอง
Nick Kennedy

1
ดูเหมือนว่ามันจะไม่ทำงานอย่างถูกต้องสำหรับพยัญชนะสองตัวหรือสระ ตัวอย่างเช่นfnpfaควรเป็นอักขระตัวเดียวแต่จบลงด้วย루ㅔㄹㅁ
Nick Kennedy

กำลังแก้ไข ไม่ควรมีราคามากเกินไป
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 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
Nick Kennedy

ทำงานได้ดีในขณะนี้ ฉันคิดว่าคุณได้ทำการอัปเดตคุณแล้ว แต่ยังไม่ได้ไปที่นี่เลย!
Nick Kennedy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.