Na temat klawiatur

15

Keep Talking and Nobody Explodes to lokalna gra wieloosobowa, w której jeden gracz ma kontrolę nad wirtualną „bombą” i musi być prowadzony przez innego gracza, „eksperta”, który ma dostęp do instrukcji usuwania bomb. Jednym z modułów do rozbrojenia w grze jest moduł klawiatury, z którym będziemy mieli do czynienia w tym wyzwaniu.

Zadanie

Wejście rozpocznie się od jednego wiersza drukowalnych znaków ASCII z wyjątkiem spacji (0x21 do 0x7E). Reprezentują one widoczne przyciski klawiatury.

Następne kilka linii będzie reprezentować „klucze” - tylko jeden wiersz będzie zawierał wszystkie znaki pierwszego wiersza, niekoniecznie w kolejności. Twoim zadaniem jest wyprowadzanie znaków z klawiatury, w kolejności zgodnej linii klawiszy.

Na przykład, jeśli dane wejściowe były

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

wówczas klawiatura przyciski 5, ~, Fi y. Tylko czwarta linia klawiszy ~Fi(&5gyzawiera wszystkie te znaki, więc znaki klawiatury wypisujemy w kolejności, w jakiej się pojawiają, tj ~F5y.

Zasady i wyjaśnienia

  • Wejście musi być pojedynczym ciągiem wielowierszowym, z przyciskami klawiatury i wierszami klawiszy w osobnych wierszach.
  • Będzie dokładnie jedna linia klucza, która zawiera wszystkie znaki na klawiaturze.
  • Każda linia, tj. Początkowa linia klawiatury i następujące po niej linie klawiszy, nie będą miały zduplikowanych znaków.
  • W przeciwieństwie do gry, nie możesz zakładać niczego o liczbie znaków na klawiaturze, długości każdej linii klawiszy lub liczbie linii klawiszy. Jednak wszystkie kluczowe linie mają tę samą długość.
  • Dane wyjściowe mogą zawierać jeden opcjonalny końcowy znak nowej linii. Podobnie możesz przyjąć w obu przypadkach opcjonalny końcowy znak nowej linii w danych wejściowych, ale proszę podać w swojej odpowiedzi, czy potrzebujesz założenia.
  • Chociaż wydaje się to już powszechną praktyką , stwierdzę wprost: zakończenie z błędem jest w porządku dla tego wyzwania, pod warunkiem, że wyjście STDOUT jest poprawne (jeśli jest to wybrana przez ciebie forma wyjścia). Mamy nadzieję, że ułatwi to obsługę danych wejściowych.

Przypadki testowe

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

Wyjście: 7 . Tylko ostatni wiersz zawiera 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

Wyjście : 0b~. Czwarta linia klucza zawiera już znaki w odpowiedniej kolejności.

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

Wyjście : zTuM. Kluczowa linia jest czwartą, chociaż trzecia linia kluczowa jest bliskie.

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

Wyjście : n1j@o<G. Kluczowa linia jest drugą ostatnią linią.

Punktacja

To jest , więc kod w najmniejszej liczbie bajtów wygrywa.

Sp3000
źródło
Czy STDOUT jest jedyną akceptowalną metodą wyjściową, czy też dozwolona jest również wartość zwracana przez funkcję?
Zgarb,
@ Wejście i wyjście funkcji Zgarb jest w porządku
Sp3000,
westchnienie Mam rozwiązanie, które działa dla jednego przypadku testowego ... zbyt wiele znaków specjalnych w innych przypadkach testowych. No cóż.
Kyle Kanos

Odpowiedzi:

11

CJam, 13 12 bajtów

qN/(f&{,}$W=

Sprawdź to tutaj.

Wyjaśnienie

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
źródło
8

Pyth, 10

@zhf!-zT.z

Wypróbuj online

Wyjaśnienie

@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
źródło
3

Haskell, 49 bajtów

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

Pierwsza linia definiuje funkcję pomocnika g, nienazwana funkcja w drugiej linii jest moją odpowiedzią.

Wyjaśnienie

Algorytm jest oczywisty: podziel wejście na linie, znajdź linię zawierającą wszystkie znaki pierwszego wiersza i odfiltruj wszystkie pozostałe znaki w tej linii.

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
źródło
3

Prolog, 204 190 bajtów

To mogłoby być miłym wyzwaniem dla Prologa, gdyby nie połączone wymagania dotyczące wprowadzania danych wielowierszowych oraz znaków nieskalowanych „i” na wejściu. Istnieje duża część kodu (p i r) do odczytu pliku jako znaku kody, które musiałem zrobić, aby wprowadzić dane nieskalowane w kilku wierszach.

Gdyby tylko „istniał jako znak nieskalowany, mógłbym odczytać dane wejściowe jako ciąg
.
Jeśli wejście nie było wielowierszowe, powiedzmy zamiast tego oddzielone spacją, mógłbym odczytać je jako jedną linię do kodów.

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

Jak to działa

  1. Otwiera plik t (który zawiera wszystkie dane wejściowe) do odczytu
  2. Przeczytaj wszystkie wiersze jako kody znaków i umieść na liście list (1 lista na wiersz)
  3. Powtarza się nad listami ogona i sprawdza, czy lista nagłówków istnieje jako podzbiór tej listy
  4. Przecina dopasowaną listę z głową, aby uzyskać poszukiwane postacie we właściwej kolejności
  5. Drukuje rozwiązanie

Jak uruchomić
Program jest uruchamiany za pomocą polecenia:
p.
Plik o nazwie t zawierający dane wejściowe musi znajdować się w tym samym katalogu.

Edycja: Zapisano 14 bajtów poprzez ujednolicenie 2 klauzul q z OR.

Emigna
źródło
2

MATLAB, 107 bajtów

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

W rezultacie był to bardzo niechlujny fragment kodu ...

Podczas uruchamiania otwierane jest okno dialogowe wprowadzania, w którym można wkleić ciąg wielu wierszy (znaki nowej linii są konwertowane na spacje, a wynikiem będzie komórka z 1 bardzo długim ciągiem). Zdecydowałem się przekonwertować wynikową komórkę na znak, który umożliwia podział na spacje (wynikiem jest tablica komórek), a następnie ponownie przekonwertować na znak, aby odzyskać zamierzony kształt. Wbudowany element MATLAB- a funkcja ma tutaj dobrą robotę, porównując naszą pierwszą linię z innymi liniami.

Potem robi się nieprzyjemnie ... Próbowałem wielu sposobów, aby wykluczyć pierwszą linię z mojego testu „najlepszego dopasowania” i skończyłem z tym. Szukamy linii, a następnie wykorzystać te informacje, aby pobrać indeksów (poprzez przekształcenie naszej ismember wyjście logicals), że chcemy nasze znaki wyjściowe z.

slvrbld
źródło
2

Język wolfram 106 bajtów

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

Przykładowe dane wejściowe:

wyskakujące okno wprowadzania

Wynik:

wynik wyjściowy

Objaśnienie kodu: Najpierw za pomocą InputString otrzymujemy pełny ciąg danych wejściowych, a następnie otrzymujemy pierwszy zestaw liter, dzieląc ciąg znaków na nowy wiersz i zapisując wszystkie znaki pierwszego w zmiennej o. Następnie wybieramy z pozostałych linii wejściowych te wiersze, które mają znaki pierwszego wiersza (zapisane jako zmienna o) jako podzbiór. Następnie z zaznaczoną tą linią, bierzemy elementy tej linii, które są w oryginalnym zestawie.

Edycja: Podziękowania dla Martina Büttnera za wskazówki dotyczące korzystania z notacji infix i moich niepotrzebnych zmiennych

Ian Johnson
źródło
Yay, Mathematica. Kilka wskazówek golfa: O ile mogę powiedzieć użyć ci itylko raz, więc nie ma korzyści w przypisując je do zmiennych. Prawdopodobnie możesz zapisać niektóre bajty z tej wskazówki . Nie podając oimienia. s[[1]]jest #&@@s( to samo przy drugim użyciu [[1]]). Możesz używać StringSplitbez drugiego parametru (ponieważ domyślnie dzieli się na białe znaki). SubsetQi MemberQmoże użyć notacji infix, aby zapisać bajt, np #~SubsetQ~o.
Martin Ender,
Zmieniłem to pewne, i nie zauważyliśmy, kiedy zmienił go, że tylko używany ii craz, dzięki za cynk! Potrzebuję też drugiego parametru StringSplit, ponieważ, ponieważ działo się trochę dziwnie z niektórymi postaciami interpretowanymi jako białe spacje (które nie są tak naprawdę białymi spacjami)
Ian Johnson
Ciekawy. W takim przypadku możesz zamiast tego pisać dosłowny znak nowej linii \n, aby zapisać jeden bajt, i użyć notacji infix, aby zapisać inny.
Martin Ender,
Tak, nie do końca pewien, co się dzieje z StringSplit w tym przypadku, może to być konsekwencja użycia InputString
Ian Johnson,
1

Python 2, 112 bajtów

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]

Przykładowy przebieg: Ideone

TFeld
źródło
1

JavaScript (ES6), 107 104 102 bajtów

Prezentacja Snippet do obsługi przeglądarek.

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

Skomentowano:

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
źródło