Converter texto em teclas pressionadas

10

Eu sou um robo. Comprei este teclado por causa de seu layout retangular fácil:

~`   !1   @2   #3   $4   %5   ^6   &7   *8   (9   )0   _-   +=
tab  Qq   Ww   Ee   Rr   Tt   Yy   Uu   Ii   Oo   Pp   {[   }]    \|
     Aa   Ss   Dd   Ff   Gg   Hh   Jj   Kk   Ll   :;   "'   [-enter-]
          Zz   Xx   Cc   Vv   Bb   Nn   Mm   <,   >.   ?/
                         [========= space =========]

Para imprimir texto humano, preciso convertê-lo em comandos que meus manipuladores possam interpretar. Meu manipulador esquerdo paira sobre a Shifttecla. Meu manipulador certo, no começo, passa o mouse sobre a ~tecla. Os comandos que meus manipuladores entendem são:

S      : press the shift key
s      : release the shift key
L      : move the right manipulator left by 1
R      : move the right manipulator right by 1
U      : move the right manipulator up by 1
D      : move the right manipulator down by 1
P      : press the key under the right manipulator
p      : release the key by the right manipulator

Escreva um código para converter qualquer mensagem ASCII em uma lista de comandos. A entrada pode conter qualquer número de 95 caracteres ASCII imprimíveis; possivelmente também caracteres TAB e nova linha. A saída deve ser a lista dos comandos para os manipuladores.

Então, por exemplo, para digitar Hello World!, os comandos são

SRRRRRRDDPp
sLLLUPp
RRRRRRDPp
Pp
UPp
LLLLDDDPp
SLLLUUUPp
sRRRRRRRPp
LLLLLPp
RRRRRDPp
LLLLLLPp
SLLUUPp

Redefino os manipuladores para o estado inicial antes de imprimir cada mensagem.

Existem alguns riscos mecânicos que devem ser evitados pela programação adequada:

  1. Não é LRUDpermitido mover ( ) quando a impressão ( P) é ativada
  2. Sem obstrução de manipuladores: quando um manipulador é acionado ( Sou P), o próximo comando para esse manipulador deve ser desativado ( sou p) e vice-versa
  3. Nenhuma mudança desnecessária: entre cada dois comandos de mudança ( s, S), deve haver um Pcomando

    Portanto, para imprimir ~~, os comandos SPpPpsão válidos, enquanto SPpsSPpnão são

  4. Sem sair dos limites: nenhum comando de movimento deve tentar mover o manipulador direito mais de 13 espaços para a direita ou 4 para a parte inferior da posição inicial (ou qualquer ponto para o topo ou para a esquerda)

Notas Adicionais:

  • Pressionar uma tecla desativada (como sequência de comando DDPp) resulta em nenhuma tecla pressionada e é permitida.
  • Pressionar Shift+ Tabnão tem efeito, mas Shift+ Spacee Shift+ Entertêm o mesmo efeito que sem Shift.
  • Pressionar qualquer ponto da barra de espaço e a Entertecla tem o mesmo efeito.
  • As teclas de espaço em branco na saída não têm significado, mas podem ser usadas para formatá-lo de uma maneira bonita.
anatolyg
fonte
A velocidade é um problema? Poderíamos retornar os manipuladores à sua posição inicial entre cada personagem (desde que não inclua mudanças desnecessárias, é claro)?
Engineer Toast
Sem problemas. Talvez possa ser mais interessante sem movimento extra, mas não gosto de exigir a melhor saída possível.
Anatolyg
11
Um relacionado , dois relacionados .
AdmBorkBork
2
Você ainda não definiu a tarefa ... Que caractere pode conter entrada? Qual é a tarefa real (acho que é óbvio com base no título, mas você deve especificar mesmo assim)
HyperNeutrino
3
Por que se preocupar Pp? Tanto quanto eu posso ver esses são sempre uma única ação e nem Pou ppode aparecer por conta própria.
orlp 22/05/19

Respostas:

5

Python 2 , 338 337 335 331 325 bytes

x=y=s=0
for c in input():p='`1234567890-=`	qwertyuiop[]|`asdfghjkl;\'\n```zxcvbnm,./``````` ~!@#$%^&*()_+~~QWERTYUIOP{}\\~ASDFGHJKL:"\n~~~ZXCVBNM<>?~~~~~~~ '.find(c);S=[p>61,s][c in' \n'];p%=62;Y=p/14;X=[max(x,12),min(max(x,5),10),p%14]['\n '.find(c)];print'sS'[S]*(s^S)+'LR'[X>x]*abs(X-x)+'UD'[Y>y]*abs(Y-y)+'Pp';x,y,s=X,Y,S

Experimente online!


Move diretamente de cada caractere para o próximo.

Explicação:

  • S=[c in K,s][c in' \n'], verifica se o próximo caractere deve estar em maiúsculas ou minúsculas. Se cfor um espaço ou uma nova linha, o caso permanece o mesmo.

  • X=[max(x,12),min(max(x,5),10),p%15]['\n '.find(c)]. Se cfor um espaço ou uma nova linha, é escolhida a coordenada x mais próxima da corrente (como as teclas abrangem várias colunas)

  • print'sS'[S]*(s!=S)+'LR'[X>x]*abs(X-x)+'UD'[Y>y]*abs(Y-y)+'Pp', imprime a alternância entre maiúsculas e minúsculas, o número de movimentos da coordenada x, o número de movimentos da coordenada y e, finalmente Pp, para cada caractere


Versão mais curta, se o caminho mais curto não for necessário:

Python 2 , 294 293 291 287 281 bytes

x=y=s=0
for c in input():p='`1234567890-=`	qwertyuiop[]|`asdfghjkl;\'\n```zxcvbnm,./``````` ~!@#$%^&*()_+~~QWERTYUIOP{}\\~ASDFGHJKL:"\n~~~ZXCVBNM<>?~~~~~~~ '.find(c);S=[p>61,s][c in' \n'];p%=62;X,Y=p%14,p/14;print'sS'[S]*(s^S)+'LR'[X>x]*abs(X-x)+'UD'[Y>y]*abs(Y-y)+'Pp';x,y,s=X,Y,S

Experimente online!

TFeld
fonte
É realmente necessário usar o caminho mais curto para space/ enter?
Arnauld
@Arnauld, eu hóspede não, não foi especificado, mas o exemplo vai para o espaço mais próximo (depois o)
TFeld
2

JavaScript (ES6), 263 bytes

Recebe a entrada como uma matriz de caracteres.

s=>s.map(c=>(y=i-(i=(j=`\`~1!2@3#4$5%6^7&8*9(0)-_=+00\t0qQwWeErRtTyYuUiIoOpP[{]}|\\00aAsSdDfFgGhHjJkKlL;:'"
${1e6}zZxXcCvVbBnNmM,<.>/?${1e13} `.indexOf(c))>>1),g=k=>'LRUD'[n=k?y/14:y%14,k^=n<0].repeat(n<0?-n:n))()+g(2)+['sS'[j-s&c!=' '&c!=`
`?s^=1:2]]+'Pp',i=s=0)

Experimente online!

Arnauld
fonte
1

.COM opcode, 108 104 bytes

0000h: B4 00 CD 16 BE 50 01 83 C6 03 3A 24 77 F9 0F B6
0010h: DC 03 5C 01 B4 02 CD 16 B4 02 68 00 01 A8 03 B2
0020h: 53 74 08 81 36 20 01 20 01 CD 21 84 DB 74 0B 4B
0030h: B2 52 E8 F4 FF B2 4C CD 21 C3 84 FF 74 0C FE CF
0040h: B2 44 E8 E4 FF B2 55 CD 21 C3 B2 50 CD 21 B2 70
0050h: CD 21 C3 0D FE 00 1B F1 00 1C F0 01 28 E3 01 29
0060h: D7 FF 35 D6 02 39 CC 03                        

Retire a entrada do teclado com o CapsLock desativado

Mal golfe

        org 100h
        mov ah, 0
        int 16H
        mov si, table-3
tabing: add si, 3
        cmp ah, [si]
        ja tabing
        movzx bx, ah
        add bx, [si+1]
        mov ah, 2
        int 16H
        mov ah, 2
        push 100H
        test al, 3
        mov dl, 'S'
cmd:    jz fun
        xor [cmd-1], word 0x120
        int 21H
fun:    test bl, bl
        jz bl0
        dec bx
        mov dl, 'R'
        int 21H
        call fun
        mov dl, 'L'
        int 21H
        ret
bl0:    test bh, bh
        jz bh0
        dec bh
        mov dl, 'D'
        int 21H
        call fun
        mov dl, 'U'
        int 21H
        ret
bh0:    mov dl, 'P'
        int 21H
        mov dl, 'p'
        int 21H
        ret
macro key begin, end, U, L {
        db end
        dw U*256+L-begin
}
table:
        key 0x02, 0x0D, 1, 0
        key 0x10, 0x1B, 1, 1
        key 0x1C, 0x1C, 2, 12
        key 0x1E, 0x28, 2, 1
        key 0x29, 0x29, 0, 0
        key 0x2C, 0x35, 3, 2
        key 0x39, 0x39, 4, 5
l4m2
fonte
Uma ótima idéia para fazer isso sem um LUT!
Anatolyg
11
Take input from keyboard Como nosso amigo robô, que está pedindo ajuda para usar o teclado, pode usar esse programa?
Shaun H