Sobre o assunto dos teclados

15

Keep Talking and Nobody Explodes é um jogo multiplayer local onde um jogador tem controle sobre uma "bomba" virtual e precisa ser guiado por outro jogador, o "especialista", que tem acesso a um manual de desarmamento de bombas. Um dos módulos a serem desarmados no jogo é o módulo do teclado, com o qual lidaremos neste desafio.

A tarefa

A entrada começará com uma única linha de caracteres ASCII imprimíveis, exceto o espaço (0x21 a 0x7E). Eles representam os botões do teclado visíveis para você.

As próximas linhas representam "chaves" - apenas uma linha conterá todos os caracteres da primeira linha, não necessariamente em ordem. Sua tarefa é produzir os caracteres do teclado, na ordem da linha de teclas correspondente.

Por exemplo, se a entrada foi

5~Fy
HrD7K!#}
Ui%^fHnF
)Tf;y~I5
~Fi(&5gy
,'Xd#5fZ

em seguida, os botões do teclado são 5, ~, Fe y. Somente a quarta linha da tecla ~Fi(&5gycontém todos esses caracteres, portanto, os caracteres do teclado são exibidos na ordem em que aparecem, ou seja ~F5y.

Regras e esclarecimentos

  • A entrada deve ser uma única cadeia de linhas múltiplas, com os botões do teclado e as linhas das teclas em linhas separadas.
  • Haverá exatamente uma linha de tecla que contém todos os caracteres do teclado.
  • Cada linha, ou seja, a linha inicial do teclado e as seguintes linhas principais, não terão caracteres duplicados.
  • Ao contrário do jogo, você não pode assumir nada sobre o número de caracteres do teclado, o comprimento de cada linha ou o número de linhas. No entanto, é garantido que todas as linhas principais tenham o mesmo comprimento.
  • A saída pode conter uma única nova linha à direita opcional. Da mesma forma, você pode assumir de qualquer maneira uma nova linha à direita opcional na entrada, mas especifique na sua resposta se você precisa da suposição.
  • Embora isso já pareça uma prática comum , declararei explicitamente: encerrar com um erro é aceitável para esse desafio, desde que a saída STDOUT esteja correta (se essa for a forma de saída escolhida). Espero que isso facilite o manuseio da entrada.

Casos de teste

7
4?j01C3"ch
KP.OG>QB)[
z#)Kn"I2&.
]#,D|sBFy5
Qzj*+~7DLP

Saída: 7 . Somente a última linha contém a 7.

0b~
Ob+hy{M|?;>=dtszPAR5
*8rCfsw|3O9.7Yv^x>Hq
$ip.V@n}|La:TbIt^AOF
jZ[Ec4s0|%b*$id',~J6
z*#b}-x$Ua&!O2;['T+?
NVj_X8rlhxfnS\.z}];c
bykscf.w^dnWj+}-*2g_
VP`AJH|&j5Yqmw/"9IMc

Saída : 0b~. A quarta linha-chave já contém os caracteres na ordem correta.

MTuz
bIAr>1ZUK`s9c[tyO]~W
oMGIi/H&V"BeNLua%El=
j*uYbplT:~);BM|_mPZt
Q}z5TC@=6pgr<[&uJnM%
YOA(F~_nH6T{%B7[\u#5
y&t"8zQn{wo5[Idu4g:?
[0tZG"-fm!]/|nqk,_2h
dA&C.+(byo6{7,?I}D@w

Saída : zTuM. A linha principal é a quarta, embora a terceira linha principal seja um erro grave.

o@nj<G1
f]?-<I6h2vS*%l=:}c8>LK5rMdyeon,;sE[@m(73
ibhp+2Hq6yKzIf_Zo}EO3-[*0/e&Fvd]wQU=|%`C
;}>d'cg~CPtQG&%L\)MUl419bkTZ7@]:[*H"RyYj
L^<:zXJ#kj$EFlwN%B`Dd,Cs?]xRZ*K9-uQ.@&f+
i1v'7:90R-l}FMxj`,DTWK+(n32Z4Vs[p@%*eS!d
B|^Ti/ZG$}ufL9*wE[AVt]P7CrX-)2JpD<sYxd6O
ex.$4#KarS^j+'_!B"]H[\83:(DCXUgI*Lct?qAR
^GXQoy*KW&v}n']Em~\N9)fxP(qC=7#4sRdcD6%5
;inr[&$1j_!F~@pzo#blv]}<'|fRds6OW%tEg"G2
e;0T#gfo^+!:xHDN&4V=In?AwhEv$2Fd~ZLz_\81

Saída :n1j@o<G . A linha da chave é a segunda última linha.

Pontuação

Isso é , então o código com o menor número de bytes vence.

Sp3000
fonte
STDOUT é o único método de saída aceitável ou também é permitido um valor de retorno de função?
Zgarb
A entrada e saída da função @Zgarb são boas
Sp3000
suspiro Eu tenho uma solução que funciona para um caso de teste ... muitos caracteres de escape nos outros casos de teste. Ah bem.
Kyle Kanos #

Respostas:

11

CJam, 13 12 bytes

qN/(f&{,}$W=

Teste aqui.

Explicação

q     e# Read all input.
N/    e# Split into lines.
(     e# Pull off the keypad buttons.
f&    e# Take the set intersection of each key line with the keypad, preserving the order
      e# order in the key line.
{,}$  e# Sort the results by length.
W=    e# Pick the last (longest) one.
Martin Ender
fonte
8

Pitão, 10

@zhf!-zT.z

Experimente online

Explicação

@zhf!-zT.z         ##  z = first line of input, .z = list of rest of lines
   f    .z         ##  Filter .z as T based on
    !-zT           ##  Whether removing all the letters from z that appear in T leaves an
                   ##  Empty string or not (keep the ones that give empty strings)
  h                ##  Take the first such line (necessary indexing, shouldn't ever matter)
@z                 ##  @ is setwise intersection. Pyth implements this by iterating over
                   ##  each element of the second argument and keeping values that appear
                   ##  in the first argument, which gives the intended result
FryAmTheEggman
fonte
3

Haskell, 49 bytes

g(!)(a:b)=[c|d<-b,all(!d)a,c<-d,c!a]
g elem.lines

A primeira linha define uma função auxiliar g , a função sem nome na segunda linha é a minha resposta.

Explicação

O algoritmo é óbvio: divida a entrada em linhas, encontre a linha que contém todos os caracteres da primeira linha e filtre todos os outros caracteres nessa linha.

g(!)(a:b)=                            -- g gets a binary function ! and list of strings a:b
          [c|                         -- and returns the string of characters c where
             d<-b,all(!d)a,           -- d is drawn from b and x!d holds for all x in a,
                           c<-d,c!a]  -- and c is drawn from d and c!a holds.
g elem.lines                          -- The input is split into lines and fed to g elem;
                                      -- then x!d means x `elem` d in the above.
Zgarb
fonte
3

Prolog, 204 190 bytes

Esse poderia ter sido um bom desafio para o Prolog, se não fosse pelos requisitos combinados de entrada multilinha e caracteres sem escape 'e "na entrada. Existe uma grande parte do código (p e r) para ler um arquivo como caractere códigos que é o que eu tenho que fazer para obter entrada sem escape em várias linhas.

Se apenas existisse como um caractere sem escape, eu poderia ler a entrada como uma string.
Se apenas "existisse como um caractere sem escape, eu poderia ler a entrada como um átomo.
Se a entrada não fosse multilinha, digamos, separada por espaço, eu poderia lê-la como uma linha para os códigos.

r(I,[H|T]):-read_line_to_codes(I,H),H\=end_of_file,r(I,T).
r(_,[]).
q(_,[]).
q(E,[H|T]):-subset(E,H),intersection(H,E,X),writef("%s",[X]);q(E,T).
p:-open("t",read,I),r(I,[H|T]),q(H,T),!.

Como funciona

  1. Abre o arquivo t (que contém todas as entradas) para ler
  2. Leia todas as linhas como códigos de caracteres e coloque em uma lista de listas (1 lista por linha)
  3. Repete-se nas listas finais e verifica se a lista principal existe como um subconjunto dessa lista
  4. Cruza a lista correspondente com a cabeça para obter os caracteres desejados na ordem correta
  5. Solução de impressões

Como executar O
programa é executado com o comando:
p.
O arquivo nomeado t contendo entrada deve estar no mesmo diretório.

Editar: salvou 14 bytes unificando 2 cláusulas q com OU.

Emigna
fonte
2

MATLAB, 107 bytes

b=char(strsplit(char(inputdlg),' '));[~,x]=ismember(b,b(1,:));[~,f]=min(abs(1./sum(~x')-1));b(f,(~~x(f,:)))

Isso acabou sendo um código muito desleixado ...

Ao ser executada, uma caixa de diálogo de entrada é aberta, onde uma sequência de várias linhas pode ser colada (as novas linhas são convertidas em espaços e a saída será uma célula com uma sequência muito longa). Eu escolhi converter a célula resultante em um caractere, o que possibilita a divisão nos espaços (o resultado é uma matriz de células) e, em seguida, converto novamente em char para recuperar a forma pretendida. A função integrada de membro do MATLAB faz um bom trabalho aqui ao comparar nossa primeira linha com as outras linhas.

Depois disso, fica desagradável ... Tentei várias maneiras de excluir a primeira linha da minha verificação de 'melhor correspondência' e acabei com isso. Procuramos a linha e, em seguida, usamos essas informações para obter os índices (convertendo nossa saída de membro para lógicos ) dos quais queremos nossos caracteres de saída.

slvrbld
fonte
2

Wolfram Language 106 bytes

c=Characters[InputString[]~StringSplit~"\n"];o=c[[1]];t=Select;t[t[Rest@c,#~SubsetQ~o&][[1]],o~MemberQ~#&]

Exemplo de entrada:

pop-up de entrada

Resultado:

resultado de saída

Explicação do código: Primeiro com InputString, obtemos a sequência completa de entradas, depois obtemos o primeiro conjunto de letras dividindo a sequência por nova linha e salvando todos os caracteres do primeiro na variável o. Em seguida, selecionamos no restante das linhas de entrada as linhas que possuem os caracteres da primeira linha (salvos como variável o) como um subconjunto. Depois, com essa linha selecionada, pegamos os membros dessa linha que estão no conjunto original.

Edit: Obrigado a Martin Büttner pelas dicas sobre o uso de notação infix e minhas variáveis ​​desnecessárias

Ian Johnson
fonte
Sim, Mathematica. Algumas dicas de golfe: Tanto quanto eu posso dizer-lhe usar ce iapenas uma vez, então não há nenhum benefício em atribuí-las a variáveis. Provavelmente, você pode salvar alguns bytes desta dica . Por não dar oum nome. s[[1]]é #&@@s(o mesmo para o seu segundo uso de [[1]]). Você pode usar StringSplitsem o segundo parâmetro (porque ele se divide em espaço em branco por padrão). SubsetQe MemberQpode usar notação infix para salvar um byte, por exemplo #~SubsetQ~o.
Martin Ender
Eu mudei um pouco, e não percebi, porque mudei que só usei ie cuma vez, obrigado pela dica! Além disso, eu preciso ter o segundo parâmetro para StringSplit, como havia alguma estranheza acontecendo com alguns dos personagens sendo interpretado como um espaço em branco (que não são realmente espaços em branco)
Ian Johnson
Interessante. Nesse caso, você ainda pode incorporar uma nova linha literal em vez de escrever \n, para salvar um byte e usar a notação infix para salvar outro.
Martin Ender
Sim, não inteiramente certo o que está acontecendo com StringSplit nesse caso, ele pode realmente ser uma consequência do uso InputString
Ian Johnson
1

Python 2, 112 bytes

import sys
i=sys.stdin.readlines()
print[''.join(c for c in l if c in i[0])for l in i[1:]if set(i[0])<set(l)][0]

Exemplo de execução: Ideone

TFeld
fonte
1

Javascript (ES6), 107 104 102 bytes

Demonstração de trechos para suportar navegadores.

f=x=>([a]=x.split`
`).map(y=>[...y].filter(z=>~a.indexOf(z)-x).join(x='')).find(z=>z.length==a.length)
<textarea id="i" rows="6" cols="45">o@nj<G1
f]?-<I6h2vS*%l=:}c8>LK5rMdyeon,;sE[@m(73
ibhp+2Hq6yKzIf_Zo}EO3-[*0/e&Fvd]wQU=|%`C
;}>d'cg~CPtQG&%L\)MUl419bkTZ7@]:[*H"RyYj
L^<:zXJ#kj$EFlwN%B`Dd,Cs?]xRZ*K9-uQ.@&f+
i1v'7:90R-l}FMxj`,DTWK+(n32Z4Vs[p@%*eS!d
B|^Ti/ZG$}ufL9*wE[AVt]P7CrX-)2JpD<sYxd6O
ex.$4#KarS^j+'_!B"]H[\83:(DCXUgI*Lct?qAR
^GXQoy*KW&v}n']Em~\N9)fxP(qC=7#4sRdcD6%5
;inr[&$1j_!F~@pzo#blv]}<'|fRds6OW%tEg"G2
e;0T#gfo^+!:xHDN&4V=In?AwhEv$2Fd~ZLz_\81</textarea><br /><input type="button" onclick="o.value=f(i.value)" value="Run"> Output: <input type="text" id="o" readonly />

Comentado:

f=x=>
([a]=x.split('\n')) // split input by newlines, assign first value to a
.map(y=> // map function to each line
    [...y].filter(z=> // filter characters
        ~a.indexOf(z)-x // a has character z and not the first item (x is still set)
    ).join(x='') // join characters with empty string, reset x flag
).find(z=>z.length==a.length) // return string with same length as a
nderscore
fonte