Phân tích cú pháp và xử lý đầu vào ngôn ngữ khóa


9

Hãy phân tích và xử lý Ngôn ngữ chính! Đưa ra đầu vào của một chuỗi các phím bấm và / hoặc các phím đặc biệt, hãy viết chương trình, chức năng, v.v. để xuất sản phẩm khi tất cả các hành động được xử lý dựa trên bàn phím sau:

+-------------------------------------------------------+
| ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | - | + |   |
| ` | 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                         |
+-------------------------------------------------------+                         

Các khóa xuất ra các ký tự thực tế không bao gồm khoảng trắng và thể được sửa đổi bởi các khóa khác sẽ được gọi là "khóa ký tự" và các khóa sửa đổi đầu ra của các khóa khác hoặc khoảng trắng đầu ra sẽ được gọi là "các phím đặc biệt". Các phím ký tự bảng chữ cái, sẽ được hiển thị trong đầu vào bằng chữ in hoa, có thể được sửa đổi bằng Shifthoặc Caps Lockđể tạo chữ cái in hoa và phần còn lại của các phím ký tự chỉ có thể được sửa đổi Shiftđể tạo ra các ký tự thay thế của chúng. Do đó, Atrong đầu vào tương ứng với a Akhóa ký tự, có đầu ra bình thường và đầu ra được asửa đổi, có thể lấy được bằng hoặc Shifthoặc là Caps Lockkhóa A. Mặt khác,/, tương ứng với / ?khóa ký tự, có đầu ra bình thường /và đầu ra được sửa đổi ?có thể đạt được chỉ với Shiftthời gian này.

Quy tắc

  • Đầu vào sẽ luôn là một chuỗi bao gồm một chuỗi các phím ký tự và các phím đặc biệt. Khóa đặc biệt đầy đủ để ánh xạ chuỗi cho đầu vào (nghĩa là định dạng mà chúng được đảm bảo ở đầu vào) và các hành động / đầu ra tương ứng của chúng như sau:

    • <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.
  • Một chuỗi rỗng cũng có thể là đầu vào, mà đầu ra sẽ không là gì.

  • Việc sử dụng bất kỳ tích hợp nào giải quyết vấn đề này trực tiếp đều không được phép.
  • Việc sử dụng sơ hở tiêu chuẩn là không được phép.

Các trường hợp thử nghiệm

Trình bày ở định dạng Actual String Input -> Actual String Outputtheo sau là một lời giải thích cho một vài.

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

    Đầu ra 1khi 1phím được nhấn mà không có chuyển đổi, sau đó Shift được giữ và 2phím được nhấn dẫn đến @đầu ra. Sau đó, phím Shift được giải phóng và Tab được nhấn, dẫn đến thụt 4 khoảng cách. Theo dõi, các Caps Lock phím được nhấn, sau đó R, ., K, A, P, và .bấm phím nào, kết quả đầu ra R.KAP.. Cuối cùng, một không gian duy nhất là đầu ra tiếp theo sự thay đổi dẫn đến !23đang được đầu ra khi 1, 23bấm phím nào ở cuối.

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

    Phím Shift được giữ và theo sau là Aphím, dẫn đến đầu ra Atheo sau là đầu ra bcdefgkhi B-Gnhấn phím. Sau đó, phím Shift được giữ lại thành công bởi Hphím, sau đó là đầu ra H, tiếp theo là ijkkhi I-Knhấn phím. Cuối cùng, các 1-4phím đều được sửa đổi như thay đổi được tổ chức xuống trước mỗi bấm phím kết quả đầu ra !@#$kết thúc bởi 567890khi 5-0phím đang nhấn.

  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)

    Phím xóa được nhấn vào đầu sau đó không có gì xảy ra. Sau đó, phím Return được nhấn dẫn đến một dòng mới, nó sẽ bị xóa sau khi nhấn phím backspace. Cuối cùng, trình tự tương tự (dòng mới theo sau là backspace) được lặp lại. Sau tất cả, đầu ra là một chuỗi rỗng.

  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>

    Chuỗi <RET>phải là đầu ra chuỗi thực tế . Vì vậy, điều này không nên xuất ra một dòng mới.

  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)

Đây là nên mã ngắn nhất tính bằng byte sẽ thắng!


5
Đó là một phím Xóa kỳ lạ mà bạn có ở đó ...
Dennis

1
@Dennis Chà, tôi đang mô tả các phím dựa trên bàn phím MacBook Pro của tôi, nơi phím xóa sẽ xóa ký tự trước đó. Tôi vẫn đồng ý với bạn mặc dù. Đó là một bố cục khá kỳ lạ.
R. Kap

Ah, điều đó giải thích nó. Nó được gọi là Backspace trên mỗi bàn phím mà tôi từng sở hữu. lầm bầm điều gì đó về các phím bấm bàn phím thông thường
Dennis

1
Trong thử nghiệm # 2, đầu ra có nên AbcdefgHijk!@#$567890không? Ngoài ra, trong thử nghiệm # 8, <SHFT>ở cuối chuỗi, nhưng quy tắc nêu rõ: "Đảm bảo rằng khóa ký tự sẽ thành công <SHFT>."
đồ học

@atlasologist Vâng, bạn đã đúng, và bắt tốt đẹp! Tôi quên cập nhật những cái đó.
R. Kap

Câu trả lời:


6

Mã máy 16 bit x86, 140 139 byte

Đã lưu 1 byte bằng cách thay thế DL bằng DX trong opcode thứ hai đến cuối cùng. Cũng sửa lỗi nhảy bù trong tháo gỡ để phù hợp với kết xuất hex.

Vì bản chất của nhiệm vụ yêu cầu một số dữ liệu được khởi tạo trước và câu trả lời không phải là một chương trình đầy đủ mà là một chức năng, tôi giả sử rằng có một phần dữ liệu trong chương trình và trình liên kết cập nhật kịp thời địa chỉ của dữ liệu. Trình giữ chỗ địa chỉ được ký hiệu là '????'.

Đây là một đại diện hex của mã. Các tham số là con trỏ tới chuỗi đầu vào trong SI và con trỏ tới bộ đệm đầu ra trong DI. Các chuỗi được coi là kết thúc NULL.

8D1E????89F931D231C0FCAC84C07419D0EA72173C3C74263C41720A3C5A770684F675020C20AAEBE2AAC33C41720B3C5A76F324170402D7EBEC2C27EBF94646AC46240F74154848741748741948741A4848741A39F973B34FEBB04680F601EBAAB020AAAAAAB020EBBCB00AEBB84642EB99

Nội dung của bảng ánh xạ (25 byte):

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

Số lượng byte chiếm cả mã và dữ liệu.

Tháo gỡ:

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

Đối với tập lệnh 32 bit, mã hoàn toàn giống nhau ngoại trừ lệnh đầu tiên dài hơn 2 byte do địa chỉ 32 bit (8d1d ????????? eb ebx, ds: ??????? ?)


Công việc tốt đẹp! :) Nếu nó không quá nhiều rắc rối, bạn có thể vui lòng kiểm tra xem chương trình của bạn trả về và đầu ra icho trường hợp thử nghiệm U<RET><DEL><DEL>Ivà một chuỗi trống cho đầu vào RE<DEL><DEL>không? Tôi đã làm rõ các quy tắc một chút về khóa xóa, vì vậy nếu 2 trường hợp kiểm tra đó không hoạt động, bạn có thể vui lòng cập nhật mã của mình để nó tạo ra đầu ra chính xác cho các trường hợp kiểm tra đó không? Cảm ơn bạn!
R. Kap

Tất cả các trường hợp thử nghiệm đã thành công. Tại sao <DEL> hoạt động không chính xác? Nó chỉ là một sự sụt giảm đăng ký với kiểm tra ranh giới
meden

Được rồi Tôi chỉ muốn chắc chắn rằng chương trình của bạn hoạt động như bình thường. Câu trả lời chính xác.
R. Kap

Chúng tôi cần nhiều trường hợp đặc biệt hơn. Sẽ thú vị hơn nếu <DEL> không thể xóa <RET>. Tôi có thể thực hiện nó chỉ trong 3 byte.
meden

1
Khi gõ vào dòng lệnh của shell hoàn toàn có ý nghĩa. Nhưng, nhớ bạn, tôi không yêu cầu thay đổi quy tắc. Cảm ơn về thử thách.
meden

4

Võng mạc, 136 byte

Có lẽ có thể được chơi golf hơn nữa.

<SHFT>
§
<SPC>

<TAB>

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

tôi (`
¶
[^ §]?

Xác nhận tất cả các testcase. (Sửa đổi một chút để chạy tất cả các testcase cùng một lúc.)


Caps + Shift + A = a trên bàn phím của tôi.
Neil

@Neil Vâng, cho mục đích của thử thách này (và theo bàn phím Macbook Pro của tôi) Caps+Shift+A = A. Man bàn phím của tôi thật kỳ lạ ...
R. Kap

CAPS + SHIFT + A = A. Tại sao trên trái đất sẽ đảo ngược sự thay đổi ??
con mèo

1
@cat trong hàng triệu trên hệ thống Windows CAPS đảo ngược sự thay đổi, bất kể bạn viết bao nhiêu dấu hỏi. Bởi vì nó thuận tiện và người dùng đã quen với nó
edc65

1
Aaaand, hai giải pháp 110 byte: retina.tryitonline.net/ mài , retina.tryitonline.net/ Lời ... Tôi nghĩ rằng tôi đã hoàn thành ngay bây giờ. ;)
Martin Ender

4

JavaScript (ES6), 207

Đã cập nhật để sửa lỗi với các lần xóa lặp đi lặp lại, thậm chí một số byte ngắn hơn.

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

ít chơi gôn

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

Kiểm tra

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>


Công việc tốt! :) Nếu nó không quá nhiều rắc rối, bạn có thể vui lòng kiểm tra xem chương trình của bạn trả về và đầu ra Icho trường hợp thử nghiệm U<RET><DEL><DEL>Ivà một chuỗi trống cho đầu vào RE<DEL><DEL>không? Tôi đã làm rõ các quy tắc một chút về khóa xóa, vì vậy nếu 2 trường hợp kiểm tra đó không hoạt động, bạn có thể vui lòng cập nhật mã của mình để nó tạo ra đầu ra chính xác cho các trường hợp kiểm tra đó không? Cảm ơn bạn!
R. Kap

Sai cho các trường hợp thử nghiệm. Tôi phải thực hiện một cách tiếp cận khác. Trong khi đó, tôi đoán U<RET><DEL>Inên cung cấp cho ikhôngI
edc65

Vâng, bạn đúng về điều đó. Cập nhật.
R. Kap
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.