На предмет клавиатур


15

Keep Talking и Nobody Explodes - это локальная многопользовательская игра, в которой один игрок контролирует виртуальную «бомбу» и должен управляться другим игроком, «экспертом», который имеет доступ к руководству по обезвреживанию бомб. Одним из модулей, которые нужно разоружить в игре, является модуль клавиатуры, с которым мы будем иметь дело в этом вызове.

Задание

Ввод начнется с одной строки печатных символов ASCII, кроме пробела (от 0x21 до 0x7E). Они представляют кнопки клавиатуры, видимые для вас.

Следующие несколько строк будут представлять «ключи» - только одна строка будет содержать все символы первой строки, причем не обязательно по порядку. Ваша задача - выводить символы клавиатуры в порядке совпадения строк клавиш.

Например, если входной сигнал был

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

то клавиатура кнопки 5, ~, Fи y. Только четвёртая ключевая строка ~Fi(&5gyсодержит все из этих символов, поэтому мы выводим на клавиатуры символов в том порядке , в котором они появляются, то есть ~F5y.

Правила и разъяснения

  • Ввод должен быть одной многострочной строкой, с кнопками клавиатуры и клавишами в отдельных строках.
  • Там будет ровно одна строка клавиш, которая содержит все символы клавиатуры.
  • Каждая строка, т. Е. Начальная строка клавиатуры и последующие строки клавиш, не будет содержать повторяющихся символов.
  • В отличие от игры, вы не можете предполагать что-либо о количестве символов на клавиатуре, длине каждой клавиши или количестве клавиш. Однако все ключевые строки имеют одинаковую длину.
  • Вывод может содержать один необязательный завершающий перевод строки. Точно так же вы можете предположить в любом случае о дополнительном завершающем переводе строки во входных данных, но, пожалуйста, укажите в своем ответе, если вам нужно предположение.
  • Хотя это уже кажется обычной практикой , я прямо скажу: завершение с ошибкой вполне допустимо для этой задачи, если вывод STDOUT правильный (если это выбранная вами форма вывода). Надеюсь, это облегчит обработку ввода.

Контрольные примеры

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

Выход: 7 . Только последняя строка содержит 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

Выход : 0b~. Четвёртая ключевая строка уже содержит символы в правильном порядке.

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

Выход : zTuM. Ключевая линия - 4-я, хотя 3-я ключевая линия - близкий промах.

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

Выход : n1j@o<G. Ключевая строка - вторая последняя строка.

счет

Это , поэтому выигрывает код в наименьшем количестве байтов.


Является ли STDOUT единственным приемлемым методом вывода или допустимо также возвращаемое значение функции?
Згарб

@Zgarb Функция ввода и вывода в порядке
Sp3000

вздох У меня есть решение, которое работает для одного теста ... слишком много escape-символов в других тестах. Ну что ж.
Кайл Канос

Ответы:


11

CJam, 13 12 байт

qN/(f&{,}$W=

Проверьте это здесь.

объяснение

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.

8

Пиф, 10

@zhf!-zT.z

Попробуйте онлайн

объяснение

@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

7

Pyth, 9 байт

eolN@Lz.z

демонстрация

@Lz.z: Отфильтруйте все линии для пересечения с первой линией.

olN: Заказ по длине

e: Возьми самое длинное.


3

Haskell, 49 байт

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

Первая строка определяет вспомогательную функцию g, безымянная функция во второй строке - мой ответ.

объяснение

Алгоритм очевиден: разбить ввод на строки, найти строку, содержащую все символы первой строки, и отфильтровать все остальные символы в этой строке.

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.

3

Пролог, 204 190 байт

Это могло бы стать хорошей задачей для Пролога, если бы не совместимые требования многострочного ввода и неэкранированных символов «и» во входе. Существует большой кусок кода (p и r) для чтения файла как символа коды, которые я должен был сделать, чтобы получить неэкранированный ввод в несколько строк.

Если бы только существовал как неэкранированный символ, я мог бы читать ввод как строку.
Если бы только «существовал как неэкранированный символ, я мог бы читать ввод как атом.
Если бы ввод не был многострочным, скажем, разделенным пробелом, я мог бы прочитать его как одну строку для кодов.

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

Как это работает

  1. Открывает файл т (который содержит все входные данные) для чтения
  2. Прочитать все строки в виде кодов символов и поместить в список списков (1 список в строке)
  3. Рекурсирует хвостовые списки и проверяет, существует ли головной список как подмножество этого списка
  4. Пересекает сопоставленный список с головой, чтобы получить нужные символы в правильном порядке.
  5. Печатает решение

Как запустить
программу выполняется с помощью команды:
р.
Файл namned t, содержащий входные данные, должен находиться в том же каталоге.

Редактировать: Сохранено 14 байтов путем объединения 2 q-предложений с ИЛИ.


2

MATLAB, 107 байт

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

Это оказалось очень неаккуратным фрагментом кода ...

При запуске открывается диалоговое окно ввода, в которое можно вставить многострочную строку (новые строки преобразуются в пробелы, и на выходе будет ячейка с 1 очень длинной строкой). Я решил преобразовать полученную ячейку в символ, который позволяет разделить пробелы (результат - массив ячеек), а затем снова преобразовать в символ, чтобы получить нужную форму. Встроенная в MATLAB функция ismember делает хорошую работу по сравнению нашей первой строки с другими строками.

После этого это становится неприятным ... Я пробовал много способов исключить первую строку из проверки на "лучший матч" и закончил с этим. Мы ищем строку , а затем использовать эту информацию , чтобы захватить индексы (путем преобразования нашего IsMember вывода логических выражений ) , что мы хотим , чтобы наши выходные символы.


2

Wolfram Language 106 байт

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

Пример ввода:

всплывающее окно ввода

Выход:

выходной результат

Объяснение кода: сначала с помощью InputString мы получаем полную строку ввода, затем получаем первый набор букв, разбивая строку на новую строку и сохраняя все символы первого в переменной o. Затем мы выбираем из остальных строк ввода те строки, которые содержат символы первой строки (сохраненные как переменная o) в качестве подмножества. Затем, выбрав эту строку, мы берем элементы этой строки, которые находятся в исходном наборе.

Изменить: Спасибо Мартин Бюттнер за советы по использованию инфиксной записи и мои ненужные переменные


Yay, Mathematica. Несколько советов по игре в гольф: Насколько я могу судить, вы используете cи iтолько один раз, поэтому нет смысла присваивать их переменным. Вероятно, вы можете сохранить несколько байтов из этого совета . Не давая oимя. s[[1]]есть #&@@s(то же самое для вашего второго использования [[1]]). Вы можете использовать StringSplitбез второго параметра (потому что он разделяется на пробел по умолчанию). SubsetQи MemberQможет использовать инфиксную нотацию для сохранения байта, например #~SubsetQ~o.
Мартин Эндер,

Я изменил это немного, и не заметил, поскольку я изменил это, что я только использовал iи cоднажды, спасибо за подсказку! Кроме того, мне нужен второй параметр StringSplit, так как происходили некоторые странности с некоторыми символами, интерпретируемыми как пробелы (которые на самом деле не являются пробелами)
Ian Johnson

Интересный. В этом случае вы все равно можете вставить буквальный символ новой строки вместо записи \n, чтобы сохранить один байт, и использовать инфиксную нотацию для сохранения другого.
Мартин Эндер

Да, не совсем уверен, что происходит с StringSplit в этом случае, это может на самом деле быть следствием использования InputString
Ian Johnson

1

Python 2, 112 байт

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]

Пример выполнения: Ideone


1

Javascript (ES6), 107 104 102 байта

Демонстрационная версия фрагмента поддержки браузеров.

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

комментарии:

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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.