Analisar e processar a entrada de linguagem-chave

9

Vamos analisar e processar o idioma-chave! Dada a entrada de uma sequência de pressionamentos de tecla do teclado e / ou teclas especiais, escreva um programa, função etc. que produza o produto quando todas as ações forem processadas com base no seguinte teclado:

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

As chaves que saída personagens reais não consistem de espaços em branco e são capazes de ser modificado por outras chaves serão conhecidas como "teclas de caracteres", e aqueles que modificam a saída de outras chaves ou saída de espaços em branco serão conhecidas como "teclas especiais". As teclas de caracteres do alfabeto, que serão mostradas na entrada com letras maiúsculas, podem ser modificadas com Shiftou Caps Lockpara produzir letras maiúsculas, e o restante das teclas de caracteres só pode ser modificado com Shiftpara produzir seus caracteres alternativos. Portanto, Ana entrada corresponde à a Achave de caractere, cuja saída normal é ae cuja saída modificada, obtida com a tecla Shiftou Caps Lock, é A. Por outro lado,/, que corresponde à / ?chave de caractere, possui uma saída normal de /e uma saída modificada de ?obtenível somente com Shiftesse tempo.

Regras

  • A entrada sempre será uma sequência que consiste em uma sequência de teclas de caracteres e teclas especiais. A chave especial completa para o mapeamento de strings da entrada (ou seja, o formato que eles garantem estar na entrada) e suas ações / saídas correspondentes são as seguintes:

    • <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.
  • Uma string vazia também é possível como entrada, para a qual a saída não deve ser nada.

  • O uso de qualquer built-in que resolva esse problema diretamente não é permitido.
  • O uso de brechas padrão não é permitido.

Casos de teste

Apresentado no formato Actual String Input -> Actual String Outputseguido de uma explicação para alguns.

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

    Saída 1como a 1tecla é pressionada sem alternar, então Shift é mantido pressionado e a 2tecla é pressionada, resultando na @saída. Em seguida, a tecla Shift é liberada e a tecla Tab é pressionada, resultando em um recuo com 4 espaços. Na sequência, a tecla Caps Lock está pressionado, após o qual o R, ., K, A, P, e .teclas são pressionadas, resultando na saída R.KAP.. Finalmente, um único espaço de saída, seguido por deslocamento, resultando em !23ser emitidos quando as 1, 2e 3as teclas são pressionadas no final.

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

    A tecla Shift é mantida pressionada, seguida pela Atecla, resultando na saída Aseguida pela saída bcdefgquando as B-Gteclas são pressionadas. Em seguida, a tecla Shift é pressionada novamente , seguida pela Htecla, após a qual a saída é H, seguida por ijkquando as I-Kteclas são pressionadas. Finalmente, todas as 1-4teclas são modificadas à medida que a tecla Shift é mantida pressionada antes de cada pressionamento de tecla, resultando na saída !@#$final 567890quando as 5-0teclas são pressionadas.

  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)

    A tecla Delete é pressionada no começo, após o que nada acontece. Em seguida, a tecla Return é pressionada, resultando em uma nova linha, que é excluída após a tecla backspace ser pressionada novamente. Finalmente, a mesma sequência (nova linha seguida por backspace) é repetida. Depois de tudo isso, a saída é uma string vazia.

  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>

    A string <RET>deve ser a saída real da string. Portanto, isso não deve gerar uma nova linha.

  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)

Este é um e o código mais curto em bytes vence!

R. Kap
fonte
5
Essa é uma tecla Delete estranho que você tem lá ...
Dennis
11
@Dennis Bem, estou descrevendo as teclas com base no teclado do meu MacBook Pro, onde a tecla Delete exclui o caractere anterior. Eu ainda concordo com você. É um layout bem estranho.
R. Kap
Ah, isso explica isso. É chamado Backspace em literalmente todos os teclados que já possuo. murmura algo sobre normais keypresses teclado
Dennis
11
No teste nº 2, a saída deve ser AbcdefgHijk!@#$567890? Além disso, no teste 8, <SHFT>está no final da cadeia, mas as regras declaram: "É garantido que uma chave de caractere terá êxito em <SHFT>."
atlasologist
@ atlasologist Sim, você está certo, e boa captura! Eu esqueci de atualizar aqueles.
R. Kap

Respostas:

6

Código de máquina x86 de 16 bits, 140 139 bytes

Economizou 1 byte substituindo DL por DX no penúltimo opcode. Correções de salto corrigidas também na desmontagem para corresponder ao despejo hexadecimal.

Como a natureza da tarefa requer alguns dados pré-inicializados e a resposta não é um programa completo, mas uma função, presumo que exista uma seção de dados no programa e o vinculador atualiza prontamente o endereço dos dados. O espaço reservado para o endereço é indicado por '????'.

Esta é uma representação hexadecimal do código. Os parâmetros são ponteiro para inserir a string no SI e ponteiro para o buffer de saída no DI. Presume-se que as seqüências sejam terminadas em NULL.

8D1E????89F931D231C0FCAC84C07419D0EA72173C3C74263C41720A3C5A770684F675020C20AAEBE2AAC33C41720B3C5A76F324170402D7EBEC2C27EBF94646AC46240F74154848741748741948741A4848741A39F973B34FEBB04680F601EBAAB020AAAAAAB020EBBCB00AEBB84642EB99

Conteúdo da tabela de mapeamento (25 bytes):

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

A contagem de bytes é responsável pelo código e pelos dados.

Desmontagem:

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

Para o conjunto de instruções de 32 bits, o código é absolutamente o mesmo, exceto para a primeira instrução, que possui 2 bytes a mais devido ao endereçamento de 32 bits (8d1d ???????? lea ebx, ds: ??????? ?)

meden
fonte
Bom trabalho! :) Se não houver muitos problemas, você pode verificar se o seu programa retorna e gera saída ipara o caso de teste U<RET><DEL><DEL>Ie uma sequência vazia para a entrada RE<DEL><DEL>? Esclarei as regras um pouco sobre a chave de exclusão. Portanto, se esses dois casos de teste não funcionarem, você também pode atualizar seu código para que ele produza a saída correta para esses casos de teste? Obrigado!
55568 R. Kap Kap
Todos os casos de teste foram bem-sucedidos. Por que <DEL> funcionaria incorretamente? É apenas um
decréscimo de
Tudo certo. Eu só queria ter certeza de que seu programa funcionou como deveria. Ótima resposta.
R. Kap
Precisamos de casos mais especiais. Seria mais interessante se <DEL> não pudesse excluir o <RET>. Eu posso implementá-lo em apenas 3 bytes.
Meden
11
Ao digitar na linha de comando de um shell, faz perfeitamente sentido. Mas, lembre-se, não estou pedindo a mudança de regra. Obrigado pelo desafio.
Meden
4

Retina, 136 bytes

Provavelmente pode ser jogado mais.

<SHFT>
§
<SPC>

<TAB>

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

i (`þ
¶
[^ §]? ÷

Verifique todos os casos de teste. (Ligeiramente modificado para executar todos os casos de teste de uma vez.)

Freira Furada
fonte
Caps + Shift + A = a no meu teclado.
194 Neil
@ Neil Bem, para os propósitos deste desafio (e de acordo com o teclado do meu Macbook Pro) Caps+Shift+A = A. Man meu teclado é estranho ...
R. Kap
CAPS + SHIFT + A = A. Por que diabos as tampas invertiam o turno?
cat
11
@cat em milhões no sistema Windows CAPS inverter a mudança, não importa quantos pontos de interrogação você escreva. Porque é conveniente e os usuários estão acostumados a isso
edc65
11
Ah, e duas soluções de 110 bytes: retina.tryitonline.net/… , retina.tryitonline.net/… ... Acho que já terminei por enquanto. ;)
Martin Ender
4

JavaScript (ES6), 207

Atualizado para corrigir o erro com exclusões repetidas, até alguns bytes mais curtos.

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

menos golfe

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

Teste

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
fonte
Bom trabalho! :) Se não houver muitos problemas, você pode verificar se o seu programa retorna e gera saída Ipara o caso de teste U<RET><DEL><DEL>Ie uma sequência vazia para a entrada RE<DEL><DEL>? Esclarei as regras um pouco sobre a chave de exclusão. Portanto, se esses dois casos de teste não funcionarem, você também pode atualizar seu código para que ele produza a saída correta para esses casos de teste? Obrigado!
R. Kap 5/07
Errado para esses casos de teste. Eu tenho que ter outra abordagem. Enquanto isso, eu presumo U<RET><DEL>Ideve dar inãoI
edc65
Sim, você está certo sobre isso. Atualizada.
55568 R. Kap Kap