Analizza ed elabora l'input della lingua chiave


9

Analizziamo ed elaboriamo Key-Language! Dato l'inserimento di una sequenza di tasti della tastiera e / o tasti speciali, scrivere un programma, una funzione, ecc. Che emetta il prodotto quando tutte le azioni vengono elaborate in base alla seguente tastiera:

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

I tasti di uscita effettivi caratteri non rappresentati da spazi e sono in grado di essere modificata da altri tasti saranno chiamati "tasti carattere", e quelli che modificano la produzione di altre chiavi o uscita spazi saranno note come "chiavi speciali". I tasti dei caratteri alfabetici, che verranno visualizzati nell'input con lettere maiuscole, possono essere modificati con Shifto Caps Lockper produrre lettere maiuscole, e il resto dei tasti dei caratteri può essere modificato solo Shiftper produrre i loro caratteri alternativi. Pertanto, Anell'input corrisponde al a Atasto carattere, il cui output normale è ae il cui output modificato, ottenibile con il tasto Shifto Caps Lock, è A. D'altro canto,/, che corrisponde alla / ?chiave del carattere, ha un output normale di /e un output modificato di ?ottenibile solo con Shiftquesto tempo.

Regole

  • L'input sarà sempre una stringa costituita da una sequenza di tasti carattere e tasti speciali. La chiave speciale completa per la mappatura delle stringhe per l'input (ovvero il formato in cui è garantito che siano nell'input) e le azioni / output corrispondenti sono le seguenti:

    • <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.
  • Una stringa vuota è anche possibile come input, per cui l'output non dovrebbe essere nulla.

  • L'uso di qualsiasi built-in che risolve direttamente questo problema non è consentito.
  • L'uso di scappatoie standard è vietato.

Casi test

Presentato nel formato Actual String Input -> Actual String Outputseguito da una spiegazione per alcuni.

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

    Uscita 1quando il 1tasto viene premuto senza attivare / disattivare, quindi Shift viene tenuto premuto e il 2tasto viene premuto per @generare l' uscita. Quindi il tasto Maiusc viene rilasciato e Tab viene premuto, risultando in un rientro a 4 spaziature. In seguito, i Caps viene premuto il tasto di blocco, dopo di che il R, ., K, A, P, e .si premono i tasti, con la conseguente uscita R.KAP.. Infine, un singolo spazio è uscita seguita da spostamento conseguente !23essendo uscita quando i 1, 2e 3vengono azionati al termine.

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

    Il tasto Maiusc viene tenuto premuto seguito dal Atasto, risultando in uscita Aseguita dall'uscita bcdefgquando B-Gvengono premuti i tasti. Quindi, il tasto Maiusc viene tenuto premuto nuovamente, seguito dal Htasto, dopo di che viene emesso l'output H, seguito da ijkquando i I-Ktasti vengono premuti. Infine, tutti i 1-4tasti vengono modificati man mano che si tiene premuto il tasto shift prima di ogni pressione del tasto, per cui l'output !@#$termina 567890quando i 5-0tasti vengono nuovamente premuti.

  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)

    Il tasto Elimina viene premuto all'inizio, dopo di che non accade nulla. Quindi, il tasto Invio viene premuto e si ottiene una nuova riga, che viene eliminata dopo aver premuto nuovamente il tasto Backspace. Infine, viene ripetuta la stessa sequenza (nuova riga seguita da backspace). Dopo tutto questo, l'output è una stringa vuota.

  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>

    La stringa <RET>dovrebbe essere l' output effettivo della stringa. Pertanto, ciò non dovrebbe generare una nuova riga.

  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)

Questo è quindi il codice più breve in byte!


5
È una strana chiave di cancellazione che hai lì ...
Dennis

1
@Dennis Bene, sto descrivendo i tasti basati sulla tastiera del mio MacBook Pro, in cui il tasto Canc cancella il carattere precedente. Sono comunque d'accordo con te. È un layout piuttosto strano.
R. Kap

Ah, questo lo spiega. Si chiama Backspace su ogni tastiera che abbia mai posseduto. borbotta qualcosa sui normali tasti premuti dalla tastiera
Dennis il

1
Nel test n. 2, dovrebbe essere l'output AbcdefgHijk!@#$567890? Inoltre, nel test n. 8, si <SHFT>trova alla fine della stringa, ma le regole indicano: "È garantito che una chiave di carattere riesca un <SHFT>."
atlanteologo

@atlasologo Sì, hai ragione, e bella cattura! Ho dimenticato di aggiornare quelli.
R. Kap

Risposte:


6

Codice macchina x86 a 16 bit, 140 139 byte

Salvato 1 byte sostituendo DL con DX nel penultimo opcode. Sono stati corretti anche gli offset di salto durante lo smontaggio per adattarli allo scarico esadecimale.

Poiché la natura dell'attività richiede alcuni dati pre-inizializzati e la risposta non è un programma completo ma una funzione, suppongo che ci sia una sezione di dati nel programma e che il linker aggiorni prontamente l'indirizzo dei dati. Il segnaposto dell'indirizzo è indicato con '????'.

Questa è una rappresentazione esadecimale del codice. I parametri sono puntatore alla stringa di input in SI e puntatore al buffer di output in DI. Si presume che le stringhe siano NULL.

8D1E????89F931D231C0FCAC84C07419D0EA72173C3C74263C41720A3C5A770684F675020C20AAEBE2AAC33C41720B3C5A76F324170402D7EBEC2C27EBF94646AC46240F74154848741748741948741A4848741A39F973B34FEBB04680F601EBAAB020AAAAAAB020EBBCB00AEBB84642EB99

Contenuto della tabella di mappatura (25 byte):

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

Il conteggio dei byte tiene conto sia del codice che dei dati.

Smontaggio:

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

Per il set di istruzioni a 32 bit il codice è assolutamente lo stesso ad eccezione della prima istruzione che è più lunga di 2 byte a causa dell'indirizzamento a 32 bit (8d1d ???????? lea ebx, ds: ??????? ?)


Bel lavoro! :) Se non ci sono troppi problemi, puoi verificare se il programma restituisce e restituisce l'output iper il test case U<RET><DEL><DEL>Ie una stringa vuota per l'input RE<DEL><DEL>? Ho chiarito un po 'le regole relative alla chiave di eliminazione, quindi se quei 2 casi di test non funzionano, potresti aggiornare anche il tuo codice in modo che produca l'output corretto per quei casi di test? Grazie!
R. Kap

Tutti i casi di test sono riusciti. Perché <DEL> potrebbe funzionare in modo errato? È solo un decremento del registro con controllo dei confini
data

Tutto ok. Volevo solo assicurarmi che il tuo programma funzionasse come dovrebbe. Bella risposta.
R. Kap

Abbiamo bisogno di casi più speciali. Sarebbe più interessante se <DEL> non fosse in grado di eliminare <RET>. Posso implementarlo in soli 3 byte.
data

1
Quando si digita la riga di comando di una shell ha perfettamente senso. Ma, attenzione, non sto chiedendo il cambio di regola. Grazie per la sfida
data

4

Retina, 136 byte

Probabilmente può essere ulteriormente giocato a golf.

<SHFT>
§
<SPC>

<TAB>

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

i ( `þ
¶
[^ §]? ÷

Verifica tutti i test. (Leggermente modificato per eseguire contemporaneamente tutti i test.)


Maiusc + Maiusc + A = a sulla mia tastiera.
Neil,

@Neil Bene, ai fini di questa sfida (e secondo la tastiera del mio Macbook Pro) Caps+Shift+A = A. Amico, la mia tastiera è strana ...
R. Kap

MAIUSC + MAIUSC + A = A. Perché mai i tappi dovrebbero invertire lo spostamento ??
gatto

1
@cat in milioni su MAIUSC invertire MAIUSC, indipendentemente da quanti punti interrogativi scrivi. Perché è conveniente e gli utenti sono abituati
edc65

1
Aaaand, due soluzioni da 110 byte: retina.tryitonline.net/… , retina.tryitonline.net/… ... Penso di aver finito per ora. ;)
Martin Ender il

4

JavaScript (ES6), 207

Aggiornato per correggere il bug con ripetute eliminazioni, anche alcuni byte più brevi.

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

meno 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

Test

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>


Bel lavoro! :) Se non ci sono troppi problemi, puoi verificare se il programma restituisce e restituisce l'output Iper il test case U<RET><DEL><DEL>Ie una stringa vuota per l'input RE<DEL><DEL>? Ho chiarito un po 'le regole relative alla chiave di eliminazione, quindi se quei 2 casi di test non funzionano, potresti aggiornare anche il tuo codice in modo che produca l'output corretto per quei casi di test? Grazie!
R. Kap

Sbagliato per questi casi di test. Devo adottare un altro approccio. Nel frattempo, presumo U<RET><DEL>Idovrebbe dare inonI
edc65

Sì, hai ragione. Aggiornato.
R. Kap
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.