Окно - это квадрат ASCII-искусства с нечетной длиной стороны не менее 3, с границей из одного символа вокруг края, а также вертикальными и горизонтальными штрихами в середине:
#######
# # #
# # #
#######
# # #
# # #
#######
Окно MS - это окно, в котором граница состоит только из символов M
и S
. Ваша задача - написать программу (или функцию), которая принимает строку и выводит истинное значение, если вход является допустимым окном MS, и ложное значение, если это не так.
Характеристики
- Вы можете принять входные данные как строку, разделенную новой строкой, или массив строк, представляющих каждую строку.
- Граница окна MS может содержать смесь символов M и S, но внутренняя часть всегда будет состоять из пробелов.
- Вы можете выбрать обнаружение только окон с завершающими символами новой строки или только окон без завершающих строк, но не обоих.
Тестовые случаи
Truthy:
MMM
MMM
MMM
SMSMS
M M S
SMSMM
S S M
SMSMS
MMMMMMM
M S M
M S M
MSSSSSM
M S M
M S M
MMMMMMM
Falsey:
Hello, World!
MMMM
MSSM
MS M
MMMM
MMSMM
M S.M
sSSSS
M S M
MMSMM
MMMMMMM
M M M
MMMMMMM
M M M
MMMMMMM
MMMMMMM
M M M M
MMMMMMM
M M M M
MMMMMMM
M M M M
MMMMMMM
MMSSMSSMM
M M M
S S S
S S S
MMSSMSSMM
S S S
S S S
M M M
MMSSMSSMM
code-golf
string
ascii-art
decision-problem
Esolanging Fruit
источник
источник
Ответы:
Пайк,
3431 байтПопробуй это здесь!
источник
Retina ,
6867 байтКоличество байтов предполагает кодировку ISO 8859-1.
Попробуйте онлайн!
источник
Грязь ,
3938 байтСпасибо Zgarb за сохранение 1 байта.
Попробуйте онлайн!
Я не уверен, существует ли более простой способ обеспечить квадратное соотношение сторон отдельных компонентов окна, чем использование рекурсивного нетерминала, но это, кажется, работает довольно хорошо.
объяснение
Лучше всего читать программу снизу вверх.
Это просто определяет нетерминал (о котором вы можете думать как о подпрограмме, которая соответствует прямоугольнику),
W
который соответствует илиM
илиS
(есть неявный]
в конце строки).Это определяет нетерминал,
B
который соответствует примерно четверти выходных данных, то есть одна панель окна с левой и верхней границей. Что-то вроде этого:Чтобы гарантировать, что эта панель окна является квадратной, мы определяем
B
рекурсивно. Это либо символ окнаW
, либо онB/W\ * W/\ /*
добавляет один слой справа и снизу. Чтобы увидеть, как это происходит, давайте удалим синтаксический сахар:Это то же самое, потому что горизонтальная конкатенация может быть записана либо,
AB
либоA B
, но последняя имеет более низкий приоритет, чем вертикальная конкатенация, в/
то время как для первой - более высокая. ТакB/W[ ]*
же иB
с символом окна и рядом пробелов ниже. И затем мы добавляем по горизонтали,W/[ ]/*
который является символом окна с колонкой пробелов.Наконец, мы собираем эти нетерминалы в окончательную форму окна:
Это четыре панели окна,
B
за которыми следуют строка символов окна и столбец символов окна. Обратите внимание, что мы не делаем явного утверждения о том, что четыре оконные панели имеют одинаковый размер, но если это не так, невозможно объединить их в прямоугольник.Наконец,
e`
в начале это просто конфигурация, которая говорит Грайм, чтобы проверить, что этот шаблон может быть сопоставлен со всем вводом (и он печатает0
или1
соответственно).источник
JavaScript (ES6),
115113 байтПринимает ввод как массив массивов символов (добавьте 5 байтов для массива строк) и возвращает
1
или0
. После проверки того, что высота нечетная, проверяется каждая строка, чтобы убедиться, что массив является квадратным, и каждый символ проверяется как один из символов, которые мы ожидаем в этой конкретной позиции. Изменить: Сохранено 2 байта благодаря @PatrickRoberts.источник
(...).includes(c)
чтобы~(...).search(c)
сохранить 1 байт(...?/ /:/[MS]/).test(c)
сэкономить 2 байта вместо одного.Perl,
124123119959384Следующий скрипт Perl читает одно окно-кандидат MS из стандартного ввода. Затем он выходит с нулевым статусом выхода, если кандидат является окном MS, и с ненулевым статусом выхода, если это не так.
Он работает, генерируя два регулярных выражения, одно для верхней, средней и нижней строки и одно для каждой другой строки, и проверяя входные данные по ним.
Спасибо, @ Дада. И снова.
источник
@a=<>;$s=$"x(($.-3)/2);$m="[MS]";map{$a[$_]!~($_%($./2)?"$m$s$m$s$m":"$m${m}{$.}")&&die}0..--$.
$.
в конце , чтобы избежать использования дважды$.-1
(особенно , так как первый раз это было($.-1)/2
так нужна некоторые дополнительные круглые скобки), так что$m
в$m${m}{$.}
это не ошибка. Кроме того, я только сейчас понял, но регулярные выражения должны быть окружены^...$
(так что лишний символ в конце или начале заставляет их терпеть неудачу), или короче: используйтеne
вместо!~
.ne
вместо!~
(я не должен писать сообщения, когда я не спал всего 15 минут!).^...$
Боюсь, вам придется использовать оба выражения.Mathematica, 166 байт
Безымянная функция, принимающая список символов в качестве ввода и возвращающая
True
илиFalse
. Вот менее гольфовая версия:Первая строка определяет функцию
t
, которая разделяет список длиныd
на две части, первая из которых - первая, средняя и последняя записи списка, а вторая - все остальные. Вторая строка проверяет, является ли ввод квадратным массивом в первую очередь. Четвертая строка используетt
дважды, один раз на самом входе и один раз на всех * строках ввода, чтобы отделить символы, которые должны быть"M"
или"S"
от символов, которые должны быть пробелами; затем пятая и седьмая строки проверяют, действительно ли они такие, какими они должны быть.источник
JavaScript (ES6),
108106 байтВвод: массив строк / Ввод:
0
или1
Контрольные примеры
Показать фрагмент кода
источник
JavaScript (ES6),
140138141140 байтЯ знаю, что это не число выигрышных байтов (хотя благодаря Патрику Робертсу за -3 и я понял, что оно дает ложные срабатывания для 1 вместо M / S: +3), но я сделал это немного по-другому, я ' Я новичок в этом, и это было весело ...
Принимает массив строк, по одной для каждой строки, и возвращает true или false. Новая строка добавлена для ясности (не включена в число байтов).
Вместо проверки ввода по обобщенному шаблону я создаю окно 'M' того же размера, заменяю S на M на входе и сравниваю их.
Ungolfed
Контрольные примеры
источник
f=
ее не нужно включать в число байтов, так что это фактически 138-байтовая отправка.z=-1+s/2|0
с ,z=(s-3)/2
чтобы сохранить 1 байтe.replace(/S/g,'M')==...
на,e.split`S`.join`M`==...
чтобы сохранить еще один байтz=-1+s/2|0
есть, чтобы вернуть положительное целое число для s == 1 и даже s, то есть функция возвращает false без Array (), разбив его. В противном случае необходимая логика сделала это дольше. Отличный совет по разделению / присоединению, спасибоs=1
случай, так как мое неверное регулярное выражение просто молча терпит неудачу.JavaScript (ES6),
10910710610599 байтРедактировать : Вау, Арно спас мне 6 байтов, изменив
s.split`\n`.length
наs.search`\n`
! Благодарность!Это берет единственную многострочную строку и создает
RegExp
валидацию на основе длины входной строки. Возвращаетtrue
илиfalse
. Предполагает действительное окноимеетне символ конца строки.демонстрация
источник
r=s.search('\n')
вместоsplit / length
?s=>!s.split`S`.join`M`.search([...])
могут быть удалены, не вызывая синтаксических ошибок.RegExp