Anahtar Dili Girişini Ayrıştırma ve İşleme


9

Anahtar Dili çözümleyelim ve işleyelim! Bir dizi klavye tuş basımı ve / veya özel tuş girişi girildiğinde, tüm eylemler aşağıdaki klavyeye göre işlendiğinde ürünü çıkaran bir program, işlev vb. Yazın:

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

Çıktı gerçek karakterler olduğu tuşlar değil boşluk oluşan ve vardır "karakteri tuşları" olarak bilinen olacak diğer anahtarlar değiştirilebilir mümkün, ve "özel tuşlar" olarak bilinen edilecektir boşluk diğer anahtarlar veya çıkış çıkışını değiştirmek olanlar söyledi. Girişte büyük harflerle gösterilecek olan alfabe karakter tuşları ya büyük harflerle ya Shiftda Caps Lockbüyük harf üretmek için değiştirilebilir ve karakter tuşlarının geri kalanı sadece Shiftalternatif karakterlerini üretmek için ile değiştirilebilir . Bu nedenle A, girişte a Anormal çıktısı olan ave değiştirilmiş çıktısı ya Shiftveya Caps Locktuşuyla elde edilebilen karakter tuşuna karşılık gelir A. Diğer yandan,// ?karakter anahtarına karşılık gelen , normal bir çıktısı /ve ?sadece Shiftbu zamanla elde edilebilen değiştirilmiş bir çıktısı vardır .

kurallar

  • Giriş her zaman bir dizi karakter tuşundan ve özel tuşlardan oluşan bir dize olacaktır . Girdi için dize eşlemenin tam anahtarı (yani girdide olmaları garanti edilen biçim) ve bunlara karşılık gelen eylemler / çıktılar aşağıdaki gibidir:

    • <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.
  • Giriş olarak boş bir dize de mümkündür, bunun için çıktı hiçbir şey olmamalıdır.

  • Kullanımı herhangi yerleşik olduğu çözer bu sorunu doğrudan izin verilmez.
  • Standart boşlukların kullanımına izin verilmez.

Test Durumları

Biçimde sunulur, Actual String Input -> Actual String Outputardından birkaç açıklama yapılır.

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

    Çıkış 1olarak 1anahtar bir geçiş basılırsa, o zaman basılı tutulur ve 2kilit ile sonuçlanır basılırsa @çıkış. Ardından Shift tuşu bırakılır ve Sekme tuşuna basılarak 4 aralıklı girinti oluşur. Takibi, Kilit tuşuna basıldığında Caps, bundan sonra R, ., K, A, P, ve .tuşları çıktı sonuçlanan basıldığında R.KAP.. Son olarak, tek bir boşluk çıkışı ile sonuçlanan kayma takip eder !23zaman olan çıkış 1, 2ve 3anahtarlar sonunda preslenir.

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

    Shift tuşu basılı tutulur ve ardından tuşu basılı tutulur A, sonuçta tuşlara basıldığında çıkış ve Aardından çıkış bcdefggelir B-G. Sonra, Shift tuşuna tekrar aşağı düzenlenen ugramaktadir Hçıkışı bundan sonra anahtar Hardından ijkzaman I-Ktuşlarına basıldığında. Son olarak, 1-4tuşların her biri, her tuşa basmadan önce shift tuşunun basılı tutulmasıyla değiştirilir ve sonuç , tuşlara tekrar basıldığında çıkışın !@#$bitmesi ile sonuçlanır .5678905-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)

    Başlangıçta silme tuşuna basıldıktan sonra hiçbir şey olmuyor. Ardından, Geri tuşuna basıldığında geri silme tuşuna tekrar basıldıktan sonra silinen yeni bir satır oluşur. Son olarak, aynı dizi (yeni çizgi ve ardından geri boşluk) tekrarlanır. Tüm bunlardan sonra çıktı boş bir dizedir.

  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>

    Dize <RET>, gerçek dize çıktısı olmalıdır. Böylece, bu should not çıktı yeni bir satır.

  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)

Bu yani bayttaki en kısa kod kazanır!


5
Bu orada garip bir Sil tuşu ...
Dennis

1
@Dennis Evet, silme tuşunun önceki karakteri sildiği MacBook Pro'mun klavyesini temel alan tuşları açıklıyorum. Yine de sana katılıyorum. Oldukça garip bir düzen.
R. Kap

Ah, bu açıklıyor. Bu, şimdiye kadar sahip olduğum her klavyede Backspace olarak adlandırılıyor. normal klavye tuşlarıyla ilgili bir şey mırıldanıyor
Dennis

1
Test # 2'de çıktı olmalı AbcdefgHijk!@#$567890mı? Ayrıca, # 8 testinde <SHFT>, dizenin sonundadır, ancak kurallar şunu belirtmektedir: "Bir karakter anahtarının <SHFT> başaracağı garanti edilir."
atlasologist

@ atlasologist Evet, haklısın ve güzel yakaladın! Bunları güncellemeyi unuttum.
R. Kap

Yanıtlar:


6

16-bit x 86 makine kodu, 140 139 bayt

İkinci ile son opcode arasında DL yerine DX kullanılarak 1 bayt kaydedildi. Ayrıca, sökümdeki atlama ofsetleri altıgen dökümü ile eşleşecek şekilde düzeltildi.

Görevin doğası önceden başlatılmış bazı veriler gerektirdiğinden ve yanıt tam bir program değil, bir işlev olduğundan, programda bir veri bölümü olduğunu ve bağlayıcı hemen verilerin adresini güncellediğini varsayıyorum. Adres yer tutucusu '????' ile gösterilir.

Bu, kodun onaltılı gösterimidir. Parametreler, SI'daki giriş dizesine işaretçi ve DI'daki çıkış arabelleğine işaretçidir. Dizelerin NULL ile sonlandırıldığı varsayılır.

8D1E????89F931D231C0FCAC84C07419D0EA72173C3C74263C41720A3C5A770684F675020C20AAEBE2AAC33C41720B3C5A76F324170402D7EBEC2C27EBF94646AC46240F74154848741748741948741A4848741A39F973B34FEBB04680F601EBAAB020AAAAAAB020EBBCB00AEBB84642EB99

Eşleme tablosunun içeriği (25 bayt):

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

Bayt sayısı hem kod hem de veriyi hesaba katar.

demontaj:

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-bit komut kümesi için kod, 32-bit adresleme (8d1d ???????? lea ebx, ds: ???????) 2 bayt daha uzun olan ilk komut dışında kesinlikle aynıdır. ?)


İyi iş! :) Çok fazla sorun yoksa, programınızın itest durumu için geri döndüğünü ve çıktısını U<RET><DEL><DEL>Ive giriş için boş bir dize olup olmadığını kontrol edebilir misiniz RE<DEL><DEL>? Silme anahtarı ile ilgili kuralları biraz açıkladım, bu yüzden bu 2 test durumu işe yaramazsa, lütfen kodunuzu bu test senaryoları için doğru çıktıyı üretecek şekilde güncelleyebilir misiniz? Teşekkür ederim!
R. Kap

Tüm test örnekleri başarılı oldu. <DEL> neden yanlış çalışıyor? Bu sadece sınır kontrolü ile bir kayıt
düşüşü

Tamam. Programınızın olması gerektiği gibi çalıştığından emin olmak istedim. Mükemmel cevap.
R. Kap

Daha özel durumlara ihtiyacımız var. <DEL>, <RET> öğesini silemezse daha ilginç olurdu. Sadece 3 baytta uygulayabilirim.
meden

1
Bir kabuğun komut satırına yazarken bu çok mantıklıdır. Ama, dikkat edin, kural değişikliği istemiyorum. Meydan okuma için teşekkürler.
meden

4

Retina, 136 bayt

Muhtemelen daha fazla golf yapılabilir.

<KAYDIRMASI>
§
<SPC>

<TAB>

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

i ( 'ş
¶
[^ §]? ÷

Tüm test vakalarını doğrulayın. (Tüm test senaryolarını bir kerede çalıştırmak için biraz değiştirildi.)


Klavyemdeki Caps + Shift + A = a.
Neil

@Neil Eh, bu meydan okuma amacıyla (ve Macbook Pro'nun klavyesine göre) Caps+Shift+A = A. Adamım
R. Kap

CAPS + ÜST KARAKTER + A = A. Yeryüzünde neden kapaklar kaymayı tersine çevirir?
kedi

1
Windows sistemindeki milyonlarca @cat, kaç soru işareti yazarsanız yazın, kaymayı tersine çevirir. Uygun olduğu ve kullanıcılar alıştığı için
edc65

1
Aaaand, iki 110 baytlık çözüm: retina.tryitonline.net/… , retina.tryitonline.net/… ... Sanırım şimdilik yaptım. ;)
Martin Ender

4

JavaScript (ES6), 207

Tekrarlanan silerle hatayı düzeltmek için güncellendi, hatta bazı baytlar daha kısa.

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

daha az 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

Ölçek

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>


İyi iş! :) Çok fazla sorun yoksa, programınızın Itest durumu için geri döndüğünü ve çıktısını U<RET><DEL><DEL>Ive giriş için boş bir dize olup olmadığını kontrol edebilir misiniz RE<DEL><DEL>? Silme anahtarı ile ilgili kuralları biraz açıkladım, bu yüzden bu 2 test durumu işe yaramazsa, lütfen kodunuzu bu test senaryoları için doğru çıktıyı üretecek şekilde güncelleyebilir misiniz? Teşekkür ederim!
R. Kap

Bu test senaryoları için yanlış. Başka bir yaklaşım benimsemeliyim. Bu arada, sanıyorum U<RET><DEL>Ivermelidir ideğilI
edc65

Evet, bu konuda haklısın. Güncellenmiş.
R. Kap
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.