Zum Thema Tastaturen

15

Keep Talking and Nobody Explodes ist ein lokales Multiplayer-Spiel, bei dem ein Spieler die Kontrolle über eine virtuelle "Bombe" hat und von einem anderen Spieler geführt werden muss, dem "Experten", der Zugriff auf ein Handbuch zur Bombenentfernung hat. Eines der Module, die im Spiel deaktiviert werden müssen, ist das Tastaturmodul, mit dem wir uns in dieser Herausforderung befassen werden.

Die Aufgabe

Die Eingabe beginnt mit einer einzelnen Zeile druckbarer ASCII-Zeichen mit Ausnahme von Leerzeichen (0x21 bis 0x7E). Diese stellen die für Sie sichtbaren Tasten des Tastenfelds dar.

Die nächsten Zeilen stellen "Schlüssel" dar - nur eine Zeile enthält alle Zeichen der ersten Zeile, nicht unbedingt in der richtigen Reihenfolge. Ihre Aufgabe ist es, die Tastaturzeichen in der Reihenfolge der übereinstimmenden Tastenzeile auszugeben.

Zum Beispiel, wenn die Eingabe war

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

dann über die Tastatur - Tasten sind 5, ~, Fund y. Nur die 4. Tastenzeile ~Fi(&5gyenthält alle diese Zeichen, daher geben wir die Tastaturzeichen in der Reihenfolge aus, in der sie erscheinen, d ~F5y. H.

Regeln und Erläuterungen

  • Die Eingabe muss aus einer einzigen mehrzeiligen Zeichenfolge bestehen, wobei die Tasten und Tastenzeilen der Tastatur in separaten Zeilen stehen.
  • Es wird genau eine Tastenzeile geben, die alle Tastaturzeichen enthält.
  • Jede Zeile, dh die erste Tastaturzeile und die folgenden Tastenzeilen, enthalten keine doppelten Zeichen.
  • Im Gegensatz zum Spiel dürfen Sie nichts über die Anzahl der Tastaturzeichen, die Länge jeder Tastenzeile oder die Anzahl der Tastenzeilen annehmen. Es wird jedoch garantiert, dass alle Hauptleitungen gleich lang sind.
  • Die Ausgabe kann eine einzelne optionale nachgestellte Newline enthalten. In ähnlicher Weise können Sie einen optionalen Zeilenumbruch in der Eingabe annehmen, aber geben Sie in Ihrer Antwort an, ob Sie die Annahme benötigen.
  • Obwohl dies anscheinend bereits gängige Praxis ist , sage ich ausdrücklich: Die Beendigung mit einem Fehler ist für diese Herausforderung in Ordnung, solange die STDOUT-Ausgabe korrekt ist (sofern dies Ihre gewählte Ausgabeform ist). Hoffentlich erleichtert dies die Eingabe.

Testfälle

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

Ausgang: 7 . Nur die letzte Zeile enthält 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

Ausgang : 0b~. Die 4. Tastenzeile enthält bereits die Zeichen in der richtigen Reihenfolge.

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

Ausgang : zTuM. Die Schlüsselzeile ist die 4., obwohl die 3. Schlüsselzeile ein enger Fehler ist.

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

Ausgabe :n1j@o<G . Die Schlüsselzeile ist die vorletzte Zeile.

Wertung

Das ist , also gewinnt der Code mit den wenigsten Bytes.

Sp3000
quelle
Ist STDOUT die einzig akzeptable Ausgabemethode oder ist auch ein Funktionsrückgabewert zulässig?
Zgarb,
@ Zgarb Funktionseingabe und -ausgabe sind beide in Ordnung
Sp3000 11.11.15
Seufz Ich habe eine Lösung, die für einen Testfall funktioniert ... zu viele Escape-Zeichen in den anderen Testfällen. Naja.
Kyle Kanos

Antworten:

11

CJam, 13 12 Bytes

qN/(f&{,}$W=

Teste es hier.

Erläuterung

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

Pyth, 10

@zhf!-zT.z

Probieren Sie es online aus

Erläuterung

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

Pyth, 9 Bytes

[email protected]

Demonstration

@Lz.z: Filtert alle Linien für den Schnittpunkt mit der ersten Linie.

olN: Sortieren nach Länge

e: Am längsten dauern.

isaacg
quelle
3

Haskell, 49 Bytes

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

Die erste Zeile definiert eine Hilfsfunktion g , die unbenannte Funktion in der zweiten Zeile ist meine Antwort.

Erläuterung

Der Algorithmus ist der offensichtlichste: Teilen Sie die Eingabe in Zeilen auf, suchen Sie die Zeile, die alle Zeichen der ersten Zeile enthält, und filtern Sie alle anderen Zeichen in dieser Zeile heraus.

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

Prolog, 204 190 Bytes

Dies hätte eine schöne Herausforderung für Prolog sein können, wenn nicht die kombinierten Anforderungen für die Eingabe mehrerer Zeilen und nicht entkoppelter Zeichen "und" in der Eingabe berücksichtigt worden wären. Ein großer Teil des Codes (p und r) ist vorhanden, um eine Datei als Zeichen zu lesen Ich musste das tun, um die Eingabe in mehreren Zeilen ohne Auslassungszeichen zu übernehmen.

Wenn es nur ein Zeichen ohne Auslassungszeichen gab, konnte ich die Eingabe als Zeichenfolge lesen.
Wenn es nur ein Zeichen ohne Auslassungszeichen gab, konnte ich die Eingabe als Atom lesen.
Wenn die Eingabe nicht mehrzeilig war, z. B. durch Leerzeichen getrennt, konnte ich sie als Codezeile lesen.

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),!.

Wie es funktioniert

  1. Öffnet die Datei t (die alle Eingaben enthält) zum Lesen
  2. Lesen Sie alle Zeilen als Zeichencodes und platzieren Sie sie in einer Liste von Listen (1 Liste pro Zeile)
  3. Rekursiert über Endlisten und prüft, ob die Kopfliste als Teilmenge dieser Liste vorhanden ist
  4. Schneidet die übereinstimmende Liste mit dem Kopf, um die gewünschten Zeichen in der richtigen Reihenfolge zu erhalten
  5. Druckt Lösung

So führen Sie das
Programm aus Das Programm wird mit dem folgenden Befehl ausgeführt:
p.
Die Datei mit dem Namen t, die die Eingabe enthält, muss sich im selben Verzeichnis befinden.

Edit: 14 Bytes durch Vereinheitlichung von 2 q-Sätzen mit OR gespeichert.

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

Dies endete als ein sehr schlampiges Stück Code ...

Beim Ausführen wird ein Eingabedialog geöffnet, in den eine mehrzeilige Zeichenfolge eingefügt werden kann (Zeilenumbrüche werden in Leerzeichen konvertiert und die Ausgabe ist eine Zelle mit einer sehr langen Zeichenfolge). Ich entschied mich, die resultierende Zelle in ein Zeichen umzuwandeln, das es ermöglicht, die Zwischenräume zu teilen (Ergebnis ist ein Zellenarray) und dann erneut in ein Zeichen umzuwandeln, um die beabsichtigte Form abzurufen. Die in MATLAB integrierte Member- Funktion macht hier einen guten Job, wenn es darum geht, unsere erste Zeile mit den anderen Zeilen zu vergleichen.

Danach wird es unangenehm ... Ich habe viele Möglichkeiten ausprobiert, die erste Zeile von meiner 'Best Match'-Prüfung auszuschließen, und bin dabei gelandet. Wir suchen nach der Zeile und verwenden diese Informationen dann, um die Indizes zu ermitteln (indem wir unsere ismember- Ausgabe in logische Werte konvertieren), aus denen wir unsere Ausgabezeichen erhalten möchten.

slvrbld
quelle
2

Wolfram-Sprache 106 Bytes

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

Beispiel Eingabe:

Eingabe-Popup

Ausgabe:

Ergebnis ausgeben

Erklärung des Codes: Zuerst erhalten wir mit InputString die vollständige Zeichenfolge der Eingabe, dann die erste Menge von Buchstaben, indem wir die Zeichenfolge durch Zeilenvorschub teilen und alle Zeichen der ersten Zeichenfolge in der Variablen o speichern. Als nächstes wählen wir aus den restlichen Eingabezeilen die Zeilen aus, die die Zeichen der ersten Zeile (gespeichert als Variable o) als Teilmenge haben. Wenn diese Zeile ausgewählt ist, greifen wir auf die Mitglieder dieser Zeile zu, die sich in der ursprünglichen Gruppe befinden.

Edit: Danke an Martin Büttner für die Tipps zur Verwendung der Infixnotation und meiner unnötigen Variablen

Ian Johnson
quelle
Ja, Mathematica. Einige Golf-Tipps: Soweit ich das beurteilen kann cund inur einmal, hat es keinen Vorteil, sie Variablen zuzuweisen. Sie können wahrscheinlich einige Bytes von diesem Tipp speichern . Indem ich okeinen Namen gebe . s[[1]]ist #&@@s(dasselbe für Ihre zweite Verwendung von [[1]]). Sie können StringSplitohne den zweiten Parameter verwenden (da dieser standardmäßig auf Leerzeichen aufgeteilt wird). SubsetQund MemberQkann eine Infixnotation verwenden, um ein Byte zu speichern, z #~SubsetQ~o.
Martin Ender
Ich habe es ein wenig geändert und habe nicht bemerkt, dass ich es nur einmal verwendet habe iund cdanke für den Tipp! Außerdem muss ich den zweiten Parameter haben StringSplit, da einige der Zeichen als Leerzeichen interpretiert wurden (das sind nicht wirklich Leerzeichen)
Ian Johnson
Interessant. In diesem Fall können Sie immer noch eine wörtliche Newline einbetten, anstatt zu schreiben \n, um ein Byte zu speichern, und die Infixnotation verwenden, um ein anderes zu speichern.
Martin Ender
Ja, nicht ganz sicher, was mit StringSplit in diesem Fall los ist, es könnte tatsächlich eine Folge der Verwendung von InputString sein
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]

Beispiellauf: Ideone

TFeld
quelle
1

Javascript (ES6), 107 104 102 Bytes

Snippet-Demo zur Unterstützung von Browsern.

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 />

Kommentiert:

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
quelle