Mengurai dan Memproses Input Bahasa Kunci

9

Ayo parsing dan proses Key-Language! Diberikan input dari urutan penekanan tombol keyboard dan / atau tombol khusus, tulis program, fungsi, dll. Yang menghasilkan produk ketika semua tindakan diproses berdasarkan keyboard berikut:

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

Kunci bahwa output karakter yang sebenarnya tidak terdiri dari spasi dan yang dapat dimodifikasi oleh kunci lainnya akan dikenal sebagai "kunci karakter", dan orang-orang yang memodifikasi output kunci lainnya atau output spasi akan dikenal sebagai "tombol khusus". Tombol karakter alfabet, yang akan ditampilkan pada input dengan huruf besar, dapat dimodifikasi dengan salah satu Shiftatau Caps Lockuntuk menghasilkan huruf besar, dan sisa tombol karakter hanya dapat dimodifikasi dengan Shiftuntuk menghasilkan karakter alternatif mereka. Oleh karena itu Adalam input sesuai dengan a Akunci karakter, yang output normalnya adan output modifikasinya, dapat diperoleh dengan tombol Shiftatau Caps Lock, adalah A. Di samping itu,/, yang sesuai dengan tombol / ?karakter, memiliki output normal /dan output yang dimodifikasi ?hanya dapat diperoleh dengan Shiftwaktu ini.

Aturan

  • Input akan selalu berupa string yang terdiri dari urutan tombol karakter dan tombol khusus. Kunci khusus penuh untuk pemetaan string untuk input (yaitu format mereka dijamin berada di input) dan tindakan / output yang sesuai adalah sebagai berikut:

    • <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.
  • String kosong juga dimungkinkan sebagai input, yang outputnya seharusnya tidak ada.

  • Penggunaan bawaan apa pun yang memecahkan masalah ini secara langsung dilarang.
  • Penggunaan celah standar tidak diizinkan.

Uji Kasus

Disajikan dalam format yang Actual String Input -> Actual String Outputdiikuti oleh penjelasan untuk beberapa orang.

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

    Keluaran 1saat 1tombol ditekan tanpa beralih, lalu Shift ditekan dan 2tombol ditekan menghasilkan @output. Kemudian tombol Shift dilepaskan dan Tab ditekan, menghasilkan lekukan 4 spasi. Menindaklanjuti, Caps Lock kunci ditekan, setelah itu R, ., K, A, P, dan .tombol yang ditekan, menghasilkan output R.KAP.. Akhirnya, satu ruang yang keluaran diikuti dengan pergeseran sehingga !23menjadi output ketika 1, 2dan 3tombol yang ditekan di akhir.

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

    Tombol Shift ditekan terus diikuti oleh Atombol, menghasilkan output Adiikuti oleh output bcdefgketika B-Gtombol ditekan. Kemudian, tombol Shift ditekan lagi digantikan oleh Htombol, setelah itu output H, diikuti oleh ijkketika I-Ktombol ditekan. Akhirnya, semua 1-4tombol dimodifikasi karena shift ditekan sebelum setiap penekanan tombol yang menghasilkan output !@#$selesai 567890ketika 5-0tombol ditekan kembali.

  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)

    Tombol hapus ditekan di awal dan setelah itu tidak ada yang terjadi. Kemudian, tombol Return ditekan sehingga menghasilkan baris baru, yang dihapus setelah tombol backspace ditekan lagi. Akhirnya, urutan yang sama (baris baru diikuti oleh backspace) diulang. Setelah semua ini, outputnya adalah string kosong.

  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>

    String <RET>harus berupa output string yang sebenarnya . Jadi, ini seharusnya tidak menghasilkan baris baru.

  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)

Ini adalah sehingga kode terpendek dalam byte menang!

R. Kap
sumber
5
Itu kunci Hapus yang aneh yang Anda miliki di sana ...
Dennis
1
@ Dennis Yah, saya menjelaskan kunci berdasarkan keyboard MacBook Pro saya, di mana tombol hapus menghapus karakter sebelumnya. Saya masih setuju dengan Anda. Ini tata letak yang cukup aneh.
R. Kap
Ah, itu menjelaskannya. Ini disebut Backspace pada setiap keyboard yang saya miliki. menggumamkan sesuatu tentang penekanan tombol keyboard normal
Dennis
1
Dalam tes # 2, haruskah hasilnya AbcdefgHijk!@#$567890? Juga, dalam pengujian # 8, <SHFT>adalah di akhir string, tetapi aturan menyatakan: "Dijamin bahwa kunci karakter akan berhasil <SHFT>."
atlasologist
@atlasologist Ya, Anda benar, dan tangkapan yang bagus! Saya lupa memperbarui itu.
R. Kap

Jawaban:

6

Kode mesin x86 16-bit, 140 139 byte

Disimpan 1 byte dengan mengganti DL dengan DX di opcode kedua hingga terakhir. Juga offset lompatan yang diperbaiki dalam pembongkaran untuk mencocokkan hex dump.

Karena sifat tugas membutuhkan beberapa data yang diinisialisasi, dan jawabannya bukan program lengkap tetapi fungsi, saya berasumsi bahwa ada bagian data dalam program dan tautan segera memperbarui alamat data. Tempat penampung alamat dilambangkan dengan '????'.

Ini adalah representasi hex kode. Parameternya adalah pointer ke string input di SI dan pointer ke buffer output di DI. String diasumsikan diakhiri dengan NULL.

8D1E????89F931D231C0FCAC84C07419D0EA72173C3C74263C41720A3C5A770684F675020C20AAEBE2AAC33C41720B3C5A76F324170402D7EBEC2C27EBF94646AC46240F74154848741748741948741A4848741A39F973B34FEBB04680F601EBAAB020AAAAAAB020EBBCB00AEBB84642EB99

Konten dari tabel pemetaan (25 byte):

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

Jumlah byte dihitung untuk kode dan data.

Membongkar:

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

Untuk set instruksi 32-bit kodenya benar-benar sama kecuali untuk instruksi pertama yang 2 byte lebih lama karena pengalamatan 32-bit (8d1d ???????? lea ebx, ds: ???????? ?)

meden
sumber
Kerja bagus! :) Jika tidak terlalu banyak masalah, dapatkah Anda memeriksa apakah program Anda kembali dan output iuntuk kasus uji U<RET><DEL><DEL>Idan string kosong untuk input RE<DEL><DEL>? Saya mengklarifikasi aturan sedikit tentang kunci hapus, jadi jika 2 kasus uji tidak berfungsi, bisakah Anda juga memperbarui kode Anda sehingga menghasilkan output yang benar untuk kasus uji tersebut? Terima kasih!
R. Kap
Semua uji coba berhasil. Mengapa <DEL> tidak berfungsi dengan baik? Ini hanya penurunan register dengan pemeriksaan batas
meden
Baiklah. Saya hanya ingin memastikan bahwa program Anda berfungsi sebagaimana mestinya. Jawaban yang bagus
R. Kap
Kami membutuhkan lebih banyak kasus khusus. Akan lebih menarik jika <DEL> tidak bisa menghapus <RET>. Saya bisa mengimplementasikannya hanya dalam 3 byte.
meden
1
Saat mengetikkan baris perintah shell yang masuk akal. Tapi, ingatlah, saya tidak meminta perubahan peraturan. Terima kasih atas tantangannya.
meden
4

Retina, 136 byte

Mungkin bisa bermain golf lebih lanjut.

<SHFT>
§
<SPC>

<TAB>

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

i (`þ
¶
[^ §]? ÷

Verifikasi semua testcases. (Sedikit dimodifikasi untuk menjalankan semua testcas sekaligus.)

Biarawati Bocor
sumber
Caps + Shift + A = a di keyboard saya.
Neil
@Neil Nah, untuk keperluan tantangan ini (dan sesuai dengan keyboard Macbook Pro saya) Caps+Shift+A = A. Man keyboard saya aneh ...
R. Kap
CAPS + SHIFT + A = A. Mengapa bumi akan membatasi pergeseran ??
kucing
1
@cat dalam jutaan pada sistem Windows CAPS invert shift, tidak peduli berapa banyak tanda tanya yang Anda tulis. Karena nyaman dan pengguna terbiasa
edc65
1
Aaaand, dua solusi 110 byte: retina.tryitonline.net / ... , retina.tryitonline.net/… ... Saya pikir saya sudah selesai untuk saat ini. ;)
Martin Ender
4

JavaScript (ES6), 207

Diperbarui untuk memperbaiki bug dengan penghapusan berulang, bahkan beberapa byte lebih pendek.

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

kurang golf

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

Uji

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>

edc65
sumber
Pekerjaan yang baik! :) Jika tidak terlalu banyak masalah, dapatkah Anda memeriksa apakah program Anda kembali dan output Iuntuk kasus uji U<RET><DEL><DEL>Idan string kosong untuk input RE<DEL><DEL>? Saya mengklarifikasi aturan sedikit tentang kunci hapus, jadi jika 2 kasus uji tidak berfungsi, bisakah Anda juga memperbarui kode Anda sehingga menghasilkan output yang benar untuk kasus uji tersebut? Terima kasih!
R. Kap
Salah untuk kasus uji ini. Saya harus mengambil pendekatan lain. Sementara itu, saya kira U<RET><DEL>Isebaiknya itidak memberiI
edc65
Ya, Anda benar tentang itu. Diperbarui.
R. Kap