แยกและประมวลผลการป้อนคีย์ - ภาษา


9

ลองแยกและประมวลผล Key-Language! เมื่อกำหนดอินพุตของลำดับของการกดแป้นคีย์บอร์ดและ / หรือปุ่มพิเศษเขียนโปรแกรมฟังก์ชั่น ฯลฯ ที่ส่งออกผลิตภัณฑ์เมื่อการดำเนินการทั้งหมดถูกประมวลผลตามคีย์บอร์ดต่อไปนี้:

+-------------------------------------------------------+
| ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | - | + |   |
| ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | _ | = |Del|
+-------------------------------------------------------+
|TAB| q | w | e | r | t | y | u | i | o | p | [ | ] | \ |
|   | Q | W | E | R | T | Y | U | I | O | P | { | } | | |
+-------------------------------------------------------+
|CAPS | a | s | d | f | g | h | j | k | l | ; | ' | RET |
|     | A | S | D | F | G | H | J | K | L | : | " |     |
+-------------------------------------------------------+
| SHIFT | z | x | c | v | b | n | m | , | . | / | SHIFT |
|       | Z | X | C | V | B | N | M | < | > | ? |       |
+-------------------------------------------------------+
|                                                       |
|                      SPACEBAR                         |
+-------------------------------------------------------+                         

คีย์ว่าตัวละครที่เกิดขึ้นจริงเอาท์พุทไม่ประกอบด้วยช่องว่างและมีความสามารถที่จะแก้ไขได้โดยปุ่มอื่น ๆ จะเป็นที่รู้จักในฐานะ "คีย์ตัวอักษร" และผู้ที่ปรับเปลี่ยนการส่งออกของปุ่มอื่น ๆ หรือเอาท์พุทช่องว่างจะเป็นที่รู้จักในฐานะ "ปุ่มพิเศษที่" คีย์อักขระตัวอักษรซึ่งจะแสดงในอินพุตด้วยตัวอักษรตัวพิมพ์ใหญ่สามารถแก้ไขได้ด้วยShiftหรือCaps Lockเพื่อสร้างตัวอักษรตัวพิมพ์ใหญ่และส่วนที่เหลือของคีย์อักขระสามารถแก้ไขได้ด้วยShiftเพื่อสร้างอักขระสำรองเท่านั้น ดังนั้นAในการป้อนข้อมูลที่สอดคล้องกับa Aคีย์ตัวอักษรซึ่งปกติการส่งออกเป็นaและมีการปรับเปลี่ยนการส่งออกจะได้รับกับทั้งShiftหรือที่สำคัญคือCaps Lock Aในทางกลับกัน,/ซึ่งสอดคล้องกับ/ ?คีย์อักขระมีเอาต์พุตปกติ/และเอาต์พุตที่แก้ไขซึ่ง?สามารถขอรับได้ด้วยShiftเวลานี้เท่านั้น

กฎระเบียบ

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

    • <DEL> -> Delete the previous character (including whitespace). If called when string is empty, nothing happens. If called 2 or more times in a row, 2 consecutive deletes happen. For instance, "RE<DEL><DEL>" should return an empty string ("") and also "R<RET><DEL><DEL>E" should return just "E".
    • <CAPS> -> Enable Caps Lock until <CAPS> appears again, upon which it is disabled, although it is not guaranteed to be disabled by the end of the input. Enabling this only modifies the upcoming alphabet keys resulting in them outputting only uppercase letters. For instance, "<CAPS>RE<CAPS>" results in the output "RE", but <CAPS>.<CAPS> would still result in a ".".
    • <RET> -> Add a new line.
    • <SPC> -> Add a single blank space.
    • <TAB> -> Add 4 spaces.
    • <SHFT> -> Shift is held down resulting in the alternate character of the upcoming keypress to be output, after which the key is released. For instance, "<SHFT>A" results in the output "A", "<SHFT>1" results in the output "!", and "<SHFT>1234" results in the output "!234" as only the first upcoming keypress is modified and nothing else. It is guaranteed that a character key will succeed a <SHFT>. Therefore, <SHFT><SPC> is not a possible input.
  • สตริงว่างยังสามารถเป็นอินพุตซึ่งเอาต์พุตไม่ควรเป็นอะไร

  • การใช้ใด ๆในตัวแก้ว่าปัญหานี้โดยตรงไม่ได้รับอนุญาต
  • ไม่อนุญาตให้ใช้ช่องโหว่มาตรฐาน

กรณีทดสอบ

นำเสนอในรูปแบบActual String Input -> Actual String Outputตามด้วยคำอธิบายไม่กี่

  1. 1<SHFT>2<TAB><CAPS>R.KAP.<SPC><SHFT>123 -> 1@ R.KAP. !23

    เอาท์พุท1เมื่อ1กดปุ่มโดยไม่ต้องสลับจากนั้นกด Shift ค้างไว้และ2กดปุ่มผลลัพธ์จะเกิด@ขึ้น จากนั้นแป้น Shift จะถูกปล่อยและกด Tab ทำให้เกิดการเว้นระยะห่าง 4 อัน ต่อไปนี้ขึ้น Caps Lock กดแป้นหลังจากที่R, ., K, A, Pและปุ่มกดที่มีผลในการส่งออก. R.KAP.สุดท้ายพื้นที่เดียวคือการส่งออกตามมาด้วยการเปลี่ยนแปลงที่เกิดขึ้นใน!23การเป็นเอาท์พุทเมื่อ1, 2และ3ปุ่มกดที่สิ้นสุด

  2. <SHFT>ABCDEFG<SHFT>HIJK<SHFT>1<SHFT>2<SHFT>3<SHFT>4567890 -> AbcdefgHijk!@#$567890

    ปุ่ม Shift ค้างไว้ตามด้วยAปุ่มส่งผลให้เกิดผลลัพธ์Aตามด้วยเอาต์พุตbcdefgเมื่อB-Gกดปุ่ม จากนั้นกดปุ่ม Shift ค้างไว้อีกครั้งโดยประสบความสำเร็จHหลังจากที่มีการส่งออกHตามด้วยijkเมื่อI-Kมีการกดปุ่ม ในที่สุด1-4ปุ่มจะถูกปรับเปลี่ยนทั้งหมดเมื่อกดปุ่ม shift ค้างไว้ก่อนที่จะกดแต่ละครั้งทำให้การส่งออก!@#$เสร็จสิ้น567890เมื่อ5-0กดปุ่มอีกครั้ง

  3. <CAPS>THIS<SPC>IS<SPC>IN<SPC>ALL<SPC>CAPS<CAPS><SPC>NOW<SPC>THIS<SPC>IS<SPC>IN<SPC>ALL<SPC>LOWERCASE -> THIS IS IN ALL CAPS now this is in all lowercase

  4. <TAB><SPC><TAB><SHFT>1 -> !
  5. <CAPS>WWW<CAPS>.CODEGOLF.STACKEXCHANGE<SHFT>.COM -> WWW.codegolf.stackexchange>com
  6. PROGRAMMING<CAPS><SPC>IS<SPC><CAPS>AWESOME -> programming IS awesome
  7. <DEL><RET><DEL><RET><DEL> -> "" (Empty String)

    ปุ่มลบถูกกดในการเริ่มต้นหลังจากที่ไม่มีอะไรเกิดขึ้น จากนั้นกดปุ่ม Return จะส่งผลให้มีบรรทัดใหม่ซึ่งจะถูกลบหลังจากกดปุ่ม Backspace อีกครั้ง ในที่สุดลำดับเดียวกัน (บรรทัดใหม่ตามด้วย backspace) จะถูกทำซ้ำ หลังจากทั้งหมดนี้ผลลัพธ์เป็นสตริงว่าง

  8. <SHFT>HI<SPC>HOW<SPC>ARE<SPC>YOU<SHFT>/<RET><SHFT>I<SPC><SHFT>AM<SPC>O<DEL><SHFT>GOOD<SHFT>1 -> Hi how are you?\nI Am Good!

  9. <SHFT>,<CAPS>RET<CAPS><SHFT>. -> <RET>

    สตริง<RET>ควรเป็นเอาต์พุตสตริงที่แท้จริง ดังนั้นสิ่งนี้ไม่ควรส่งออกบรรทัดใหม่

  10. <CAPS>67890,.;'[]<CAPS> -> 67890,.;'[]

  11. <CAPS><SHFT>A -> A
  12. RE<DEL><DEL> -> "" (Empty String)
  13. U<RET><DEL><DEL>I -> i
  14. <DEL><DEL><DEL>5<DEL> -> "" (Empty string)
  15. "" (Empty String) -> "" (Empty String)

นี่คือ ดังนั้นรหัสที่สั้นที่สุดในหน่วยไบต์ชนะ!


5
นั่นเป็นกุญแจสำคัญในการลบแบบแปลก ๆ ที่คุณมี ...
Dennis

1
@Dennis ดีฉันอธิบายแป้นต่างๆตามคีย์บอร์ดของ MacBook Pro โดยที่ปุ่มลบจะลบอักขระก่อนหน้า ฉันยังคงเห็นด้วยกับคุณแม้ว่า มันเป็นเลย์เอาต์ที่แปลก
R. Kap

อ่าอธิบายได้ มันเรียกว่า Backspace บนแป้นพิมพ์ทุกตัวที่ฉันเคยเป็นเจ้าของ พึมพำบางอย่างเกี่ยวกับการกดแป้นพิมพ์ปกติ
Dennis

1
ในการทดสอบ # 2 ผลลัพธ์ควรเป็นAbcdefgHijk!@#$567890อย่างไร นอกจากนี้ในการทดสอบ # 8 <SHFT>อยู่ที่จุดสิ้นสุดของสตริง แต่สถานะของกฎ: "มันรับประกันว่าคีย์อักขระจะประสบความสำเร็จ <SHFT>"
กายวิภาคศาสตร์

@atlasologist ใช่คุณพูดถูกและจับได้ดี! ฉันลืมที่จะอัปเดตเหล่านั้น
R. Kap

คำตอบ:


6

รหัสเครื่อง 16 บิต x86 140 139 ไบต์

บันทึก 1 ไบต์โดยแทนที่ DL ด้วย DX ใน opcode ที่สองถึงครั้งสุดท้าย นอกจากนี้ยังได้รับการแก้ไขกระโดด offsets ในการถอดเพื่อให้ตรงกับการถ่ายโอนข้อมูล hex

เนื่องจากลักษณะของงานต้องการข้อมูลที่เตรียมใช้งานไว้ล่วงหน้าและคำตอบไม่ใช่โปรแกรมเต็มรูปแบบ แต่เป็นฟังก์ชั่นฉันจึงคิดว่ามีส่วนข้อมูลในโปรแกรมและตัวเชื่อมโยงอัปเดตที่อยู่ของข้อมูลทันที ตัวยึดตำแหน่งที่อยู่ถูกแสดงด้วย '????'

นี่คือการแสดงเลขฐานสิบหกของรหัส พารามิเตอร์คือตัวชี้ไปยังสตริงอินพุตใน SI และตัวชี้ไปยังบัฟเฟอร์เอาต์พุตใน DI Strings จะถือว่าเป็น NULL-terminated

8D1E????89F931D231C0FCAC84C07419D0EA72173C3C74263C41720A3C5A770684F675020C20AAEBE2AAC33C41720B3C5A76F324170402D7EBEC2C27EBF94646AC46240F74154848741748741948741A4848741A39F973B34FEBB04680F601EBAAB020AAAAAAB020EBBCB00AEBB84642EB99

เนื้อหาของตารางการแมป (25 ไบต์):

"   =<_>?)!@#$%^&*( :{}|`

ไบต์นับบัญชีสำหรับรหัสและข้อมูล

ถอดชิ้นส่วน:

8d 1e ?? ??        lea    bx,ds:???? ;Load address of mapping table to BX
89 f9              mov    cx,di      ;Save pointer to output buffer in CX
31 d2              xor    dx,dx      ;DX is the status register, bit 0 - shift status
31 c0              xor    ax,ax      ;bit 8 - caps lock status
fc                 cld               ;Clear DF

_loop:
ac                 lodsb             ;Fetch next char
84 c0              test   al,al      ;If end of string found
74 19              je     _end       ;break
d0 ea              shr    dl,1       ;Copy shift flag to CF and clear it
72 17              jc     _shift     ;Branch to input procssing with shift set
3c 3c              cmp    al,0x3c    ;If AL == '<'
74 26              je     _special   ;branch to special character processing
3c 41              cmp    al,0x41    ;At this point anything
72 0a              jb     _out       ;not in 'A'..'Z' range
3c 5a              cmp    al,0x5a    ;should be printed unmodified
77 06              ja     _out
84 f6              test   dh,dh      ;If caps lock status flag is set
75 02              jne    _out       ;go to printing right away
0c 20              or     al,0x20    ;otherwise convert to lower case
_out:
aa                 stosb             ;Store AL into output buffer
eb e2              jmp    _loop      ;Continue
_end:
aa                 stosb             ;NULL-terminate the output string
c3                 ret               ;and return

_shift:
3c 41              cmp    al,0x41    ;AL in the range [0x27..0x3b] with
72 0b              jb     _xlat0     ;a couple of holes in it

3c 5a              cmp    al,0x5a    ;AL in the range 'A'..'Z'
76 f3              jbe    _out       ;Since shift is active, go print it

24 17              and    al,0x17    ;AL is 0x5b, 0x5c, 0x5d or 0x7e,
04 02              add    al,0x2     ;convert to the [0x15..0x18] range
_xlat:
d7                 xlatb             ;Lookup mapping table (AL=[BX+AL])
eb ec              jmp    _out
_xlat0:
2c 27              sub    al,0x27    ;Convert AL to be a zero-based index
eb f9              jmp    _xlat      ;Reuse lookup code

_special:                            ;The next 4 or 5 chars are special character opcode
46                 inc    si         ;Since correct input format is guaranteed
46                 inc    si         ;don't bother reading & checking all of them,
ac                 lodsb             ;just load the third one and skip the rest
46                 inc    si         ;The lower 4 bits of the 3rd char
24 0f              and    al,0xf     ;allow to differentiate opcodes

74 15              jz     _sc_caps   ;0x0
48                 dec    ax
48                 dec    ax
74 17              jz     _sc_tab    ;0x2
48                 dec    ax
74 19              jz     _sc_spc    ;0x3
48                 dec    ax
74 1a              jz     _sc_ret    ;0x4
48                 dec    ax
48                 dec    ax
74 1a              jz     _sc_shft   ;0x6

_sc_del:                             ;0xC, <DEL> opcode
39 f9              cmp    cx,di      ;Check the length of the current output
73 b3              jae    _loop      ;DI <= CX ==> NOOP
4f                 dec    di         ;Remove the last char
eb b0              jmp    _loop
_sc_caps:                            ;<CAPS> opcode
46                 inc    si         ;Consume leftover '>' from the input
80 f6 01           xor    dh,0x1     ;Flip caps lock status bit
eb aa              jmp    _loop
_sc_tab:                             ;<TAB> opcode
b0 20              mov    al,0x20    ;Space char
aa                 stosb             ;Print it three times
aa                 stosb             ;and let the <SPC> handler
aa                 stosb             ;do the last one
_sc_spc:                             ;<SPC> opcode
b0 20              mov    al,0x20    ;Space char
eb bc              jmp    _out       ;Go print it
_sc_ret:                             ;<RET> opcode
b0 0a              mov    al,0xa     ;Newline char
eb b8              jmp    _out       ;Go print it
_sc_shft:                            ;<SHFT> opcode
46                 inc    si         ;Consume leftover '>' from the input
42                 inc    dx         ;Set shift status bit (DL is guaranteed to be zero)
eb 99              jmp    _loop

สำหรับชุดคำสั่งแบบ 32 บิตรหัสจะเหมือนกันทุกประการยกเว้นคำสั่งแรกซึ่งมีความยาว 2 ไบต์เนื่องจากการกำหนดแอดเดรสแบบ 32 บิต (8d1d ????????? lea ebx, ds: ??????? ?)


เยี่ยมมาก! :) ถ้าไม่ใช่ปัญหามากเกินไปคุณช่วยกรุณาตรวจสอบว่าโปรแกรมของคุณส่งคืนและส่งออกของiสำหรับกรณีทดสอบU<RET><DEL><DEL>Iและสตริงว่างสำหรับอินพุตRE<DEL><DEL>หรือไม่ ฉันชี้แจงกฎเล็กน้อยเกี่ยวกับปุ่มลบดังนั้นถ้ากรณีทดสอบทั้งสองกรณีใช้งานไม่ได้คุณช่วยปรับปรุงรหัสของคุณเพื่อให้ได้ผลลัพธ์ที่ถูกต้องสำหรับกรณีทดสอบเหล่านั้นหรือไม่ ขอบคุณ!
R. Kap

กรณีทดสอบทั้งหมดสำเร็จ ทำไม <DEL> ถึงทำงานไม่ถูกต้อง มันเป็นเพียงการลดลงของการลงทะเบียนกับการตรวจสอบขอบเขต
meden

เอาล่ะ ฉันแค่ต้องการตรวจสอบให้แน่ใจว่าโปรแกรมของคุณทำงานตามที่ควรจะเป็น คำตอบที่ดี
R. Kap

เราต้องการกรณีพิเศษเพิ่มเติม มันน่าสนใจกว่าถ้า <DEL> ไม่สามารถลบ <RET> ฉันสามารถใช้มันในเวลาเพียง 3 ไบต์
meden

1
เมื่อพิมพ์ในบรรทัดคำสั่งของเชลล์ที่เหมาะสม แต่ใจคุณฉันไม่ได้ขอเปลี่ยนแปลงกฎ ขอบคุณสำหรับความท้าทาย
meden

4

เรติน่า 136 ไบต์

อาจจะสามารถเล่นกอล์ฟต่อไปได้

<shft>
§
<SPC>

<Tab>

<CAPS>
¶
<RET>
þ
<DEL>
÷
T`L`l` (? <= ^ (. * ¶. * ¶) *). +
?! T` - = '[] / \\ ,. w` \ _ +: "{} | <> _) @ # $% ^ & * (lL`§
§ | ¶

ฉัน ( `þ
¶
[^ §] ÷

ตรวจสอบการทดสอบทั้งหมด (แก้ไขเล็กน้อยเพื่อรันงานทดสอบทั้งหมดในครั้งเดียว)


Caps + Shift + A = a บนคีย์บอร์ดของฉัน
Neil

@Neil ดีสำหรับวัตถุประสงค์ของการท้าทายนี้ (และตามแป้นพิมพ์ Macbook Pro Caps+Shift+A = Aของฉัน) ผู้ชายแป้นพิมพ์ของฉันคือแปลก ...
อาร์ Kap

CAPS + SHIFT + A = A. ทำไมบนโลกจะแคปสลับกลับ?
แมว

1
@cat เป็นล้านในระบบ Windows การสลับกลับ CAPS ไม่ว่าคุณจะเขียนคำถามจำนวนเท่าใด เพราะสะดวกและผู้ใช้ก็
คุ้นเคย

1
Aaaandโซลูชั่น 110 ไบต์สองรายการ: retina.tryitonline.net/… , retina.tryitonline.net/ ...... ฉันคิดว่าตอนนี้ฉันเสร็จแล้ว ;)
Martin Ender

4

JavaScript (ES6), 207

อัปเดตเพื่อแก้ไขข้อบกพร่องด้วยการลบซ้ำ ๆ แม้บางไบต์ก็สั้นลง

s=>s.replace(/<\w+>|./g,x=>(k=x[3])=='L'?o=o.slice(0,-1):k=='P'?l=!l:k=='F'?s=0:o+=k?k<'C'?'    ':k<'D'?' ':`
`:s?l?x.toLowerCase():x:s=")!@#$%^&*("[x]||'_={}|:"<>?'["-+[]\\;',./".indexOf(x)]||x,l=s,o='')&&o

golfed น้อย

s=>s.replace( /<\w+>|./g, x =>
  (k=x[3]) == 'L' ? o = o.slice(0,-1)
  : k == 'P' ? l = !l
  : k == 'F' ? s = 0
  : o+= k ? k < 'C' ? '    ' : k < 'D' ? ' ' : '\n'
  : s ? l ? x.toLowerCase() : x
  : s = ")!@#$%^&*("[x] || '_={}|:"<>?' ["-+[]\\;',./".indexOf(x)] || x,
  l = s, o = ''
) && o

ทดสอบ

F=
s=>s.replace(/<\w+>|./g,x=>(k=x[3])=='L'?o=o.slice(0,-1):k=='P'?l=!l:k=='F'?s=0:o+=k?k<'C'?'    ':k<'D'?' ':`
`:s?l?x.toLowerCase():x:s=")!@#$%^&*("[x]||'_={}|:"<>?'["-+[]\\;',./".indexOf(x)]||x,l=s,o='')&&o

console.log=(...x)=>O.textContent+=x.join` `+'\n'

;[["1<SHFT>2<TAB><CAPS>R.KAP.<SPC><SHFT>123", "1@    R.KAP. !23"]
,["<SHFT>ABCDEFG<SHFT>HIJK<SHFT>1<SHFT>2<SHFT>3<SHFT>4567890", "AbcdefgHijk!@#$567890"]
,["<CAPS>THIS<SPC>IS<SPC>IN<SPC>ALL<SPC>CAPS<CAPS><SPC>NOW<SPC>THIS<SPC>IS<SPC>IN<SPC>ALL<SPC>LOWERCASE", "THIS IS IN ALL CAPS now this is in all lowercase"]
,["<TAB><SPC><TAB><SHFT>1", "         !"]
,["<CAPS>WWW<CAPS>.CODEGOLF.STACKEXCHANGE<SHFT>.COM", "WWW.codegolf.stackexchange>com"]
,["PROGRAMMING<CAPS><SPC>IS<SPC><CAPS>AWESOME", "programming IS awesome"]
,["<DEL><RET><DEL><RET><DEL>", ""]
,["<SHFT>HI<SPC>HOW<SPC>ARE<SPC>YOU<SHFT>/<RET><SHFT>I<SPC><SHFT>AM<SPC>O<DEL><SHFT>GOOD<SHFT>1", "Hi how are you?\nI Am Good!"]
,["<SHFT>,<CAPS>RET<CAPS><SHFT>.", "<RET>"]
,["<CAPS>67890,.;'[]<CAPS>", "67890,.;'[]"]
,["<CAPS><SHFT>A", "A"]
,["U<RET><DEL><DEL>I", "i"]
,["RE<DEL><DEL>", ""]
,["", ""]].forEach(t=>{
  var i=t[0],k=t[1],r=F(i)
  console.log(
    k==r?'OK':'KO',i,'\n->',r,k==r?'\n':'(should be ->'+k+')\n'
  )
})
<pre id=O></pre>


งานที่ดี! :) ถ้าไม่ใช่ปัญหามากเกินไปคุณช่วยกรุณาตรวจสอบว่าโปรแกรมของคุณส่งคืนและส่งออกของIสำหรับกรณีทดสอบU<RET><DEL><DEL>Iและสตริงว่างสำหรับอินพุตRE<DEL><DEL>หรือไม่ ฉันชี้แจงกฎเล็กน้อยเกี่ยวกับปุ่มลบดังนั้นถ้ากรณีทดสอบทั้งสองกรณีใช้งานไม่ได้คุณช่วยปรับปรุงรหัสของคุณเพื่อให้ได้ผลลัพธ์ที่ถูกต้องสำหรับกรณีทดสอบเหล่านั้นหรือไม่ ขอบคุณ!
R. Kap

ผิดสำหรับกรณีทดสอบเหล่านี้ ฉันต้องใช้วิธีอื่น ในขณะเดียวกันผมเข้าใจU<RET><DEL>Iควรให้iไม่ได้I
edc65

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