Sobre el tema de los teclados

15

Keep Talking and Nobody Explodes es un juego multijugador local en el que un jugador tiene control sobre una "bomba" virtual y debe ser guiado por otro jugador, el "experto", que tiene acceso a un manual de desactivación de bombas. Uno de los módulos que se desarmará en el juego es el módulo de teclado, que es lo que trataremos en este desafío.

La tarea

La entrada comenzará con una sola línea de caracteres ASCII imprimibles, excepto el espacio (0x21 a 0x7E). Estos representan los botones del teclado visibles para usted.

Las siguientes líneas representarán "claves": solo una línea contendrá todos los caracteres de la primera línea, no necesariamente en orden. Su tarea es generar los caracteres del teclado, en el orden de la línea de teclas correspondiente.

Por ejemplo, si la entrada fue

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

a continuación, los botones del teclado son 5, ~, Fy y. Solo la cuarta línea de tecla ~Fi(&5gycontiene todos estos caracteres, por lo que mostramos los caracteres del teclado en el orden en que aparecen, es decir ~F5y.

Reglas y aclaraciones

  • La entrada debe ser una sola cadena multilínea, con los botones del teclado y las líneas de teclas en líneas separadas.
  • Habrá exactamente una línea de tecla que contiene todos los caracteres del teclado.
  • Cada línea, es decir, la línea inicial del teclado y las siguientes líneas de teclas, no tendrán caracteres duplicados.
  • A diferencia del juego, no puede asumir nada sobre el número de caracteres del teclado, la longitud de cada línea de tecla o el número de líneas de tecla. Sin embargo, todas las líneas clave tienen la misma longitud garantizada.
  • La salida puede contener una nueva línea final opcional. De manera similar, puede asumir de cualquier manera una nueva línea final opcional en la entrada, pero especifique en su respuesta si necesita la suposición.
  • Aunque esto ya parece ser una práctica común , declararé explícitamente: terminar con un error está bien para este desafío, siempre que la salida STDOUT sea correcta (si esta es su forma de salida elegida). Esperemos que esto facilite el manejo de las entradas.

Casos de prueba

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

Salida: 7 . Solo la última línea contiene 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

Salida : 0b~. La cuarta línea clave ya contiene los caracteres en el orden correcto.

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

Salida : zTuM. La línea clave es la cuarta, aunque la tercera línea es una falta cercana.

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

Salida : n1j@o<G. La línea clave es la segunda última línea.

Puntuación

Este es el , por lo que gana el código en la menor cantidad de bytes.

Sp3000
fuente
¿Es STDOUT el único método de salida aceptable, o también se permite un valor de retorno de función?
Zgarb
La entrada y la salida de la función @Zgarb están bien
Sp3000,
suspiro Tengo una solución que funciona para un caso de prueba ... demasiados caracteres de escape en los otros casos de prueba. Oh bien.
Kyle Kanos

Respuestas:

11

CJam, 13 12 bytes

qN/(f&{,}$W=

Pruébalo aquí.

Explicación

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
fuente
8

Pyth, 10

@zhf!-zT.z

Pruébalo en línea

Explicación

@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
fuente
7

Pyth, 9 bytes

[email protected]

Demostración

@Lz.z: Filtre todas las líneas para la intersección con la primera línea.

olN: Ordenar por longitud

e: Toma el más largo.

isaacg
fuente
3

Haskell, 49 bytes

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

La primera línea define una función auxiliar g, la función sin nombre en la segunda línea es mi respuesta.

Explicación

El algoritmo es el obvio: divida la entrada en líneas, encuentre la línea que contiene todos los caracteres de la primera línea y filtre todos los demás caracteres en esa línea.

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
fuente
3

Prólogo, 204 190 bytes

Esto podría haber sido un buen desafío para Prolog si no hubiera sido por los requisitos combinados de entrada multilínea y caracteres sin escape 'y' en la entrada. Existe una gran parte del código (p y r) para leer un archivo como carácter códigos que es lo que tuve que hacer para tomar la entrada sin escape en varias líneas.

Si solo existiera como un carácter sin escape, podría leer la entrada como una cadena.
Si solo "existiera como un carácter sin escape, podría leer la entrada como un átomo".
Si la entrada no fuera multilínea, digamos separada por espacio, podría leerla como una línea para los 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 el archivo t (que contiene todas las entradas) para leer
  2. Lea todas las líneas como códigos de caracteres y colóquelas en una lista de listas (1 lista por fila)
  3. Se repite sobre las listas de cola y comprueba si la lista de cabecera existe como un subconjunto de esa lista
  4. Intersecta la lista coincidente con la cabeza para obtener los caracteres deseados en el orden correcto
  5. Solución de impresiones

Cómo ejecutar El
programa se ejecuta con el comando:
p.
El archivo nombrado t que contiene la entrada tiene que estar en el mismo directorio.

Editar: se guardaron 14 bytes al unificar 2 cláusulas q con OR.

Emigna
fuente
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,:)))

Esto terminó siendo un código muy descuidado ...

Cuando se ejecuta, se abre un diálogo de entrada donde se puede pegar una cadena de varias líneas (las nuevas líneas se convierten en espacios y la salida será una celda con 1 cadena muy larga). Elegí convertir la celda resultante en un carácter que permite dividir en los espacios (el resultado es una matriz de celdas) y luego convertir de nuevo a carácter para recuperar la forma deseada. La función ismember incorporada de MATLAB hace un buen trabajo aquí al comparar nuestra primera línea con las otras líneas.

Después de eso se vuelve desagradable ... He intentado muchas formas de excluir la primera línea de mi verificación de 'mejor coincidencia' y terminé con esto. Buscamos la línea y después utilizar esta información para agarrar los índices (mediante la conversión de nuestra IsMember salida a Logicals) que queremos que nuestros caracteres de salida de.

slvrbld
fuente
2

Wolfram Language 106 bytes

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

Entrada de ejemplo:

ventana emergente de entrada

Salida:

resultado de salida

Explicación del código: Primero con InputString obtenemos la cadena completa de entrada, luego obtenemos el primer conjunto de letras dividiendo la cadena por una nueva línea y guardando todos los caracteres del primero en la variable o. A continuación, seleccionamos del resto de las líneas de entrada aquellas líneas que tienen los caracteres de la primera línea (guardados como variable o) como un subconjunto. Luego, con esa línea seleccionada, tomamos los miembros de esa línea que están en el conjunto original.

Editar: Gracias a Martin Büttner por los consejos sobre el uso de la notación infija y mis variables innecesarias.

Ian Johnson
fuente
Yay, Mathematica. Algunas pistas de golf: por lo que puedo decir, use cy isolo una vez, por lo que no hay beneficio en asignarlas a variables. Probablemente pueda guardar algunos bytes de este consejo . Al no dar oun nombre. s[[1]]es #&@@s(lo mismo para su segundo uso de [[1]]). Puede usar StringSplitsin el segundo parámetro (porque se divide en espacios en blanco de forma predeterminada). SubsetQy MemberQpuede usar la notación infija para guardar un byte, por ejemplo #~SubsetQ~o.
Martin Ender
Lo cambié un poco, y no me di cuenta, ya que lo cambié, que solo lo usé iy cuna vez, ¡gracias por el consejo! Además, necesito tener el segundo parámetro para StringSplit, ya que había algunas rarezas con algunos de los personajes interpretados como espacios en blanco (que no son realmente espacios en blanco)
Ian Johnson
Interesante. En ese caso, aún puede incrustar una nueva línea literal en lugar de escribir \n, para guardar un byte, y usar la notación infija para guardar otro.
Martin Ender
Sí, no estoy completamente seguro de lo que está sucediendo con StringSplit en ese caso, en realidad podría ser una consecuencia del uso de 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]

Ejemplo de ejecución: Ideone

TFeld
fuente
1

Javascript (ES6), 107 104 102 bytes

Fragmento de demostración para admitir 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
fuente