Самозванцы в зоопарке


42

Вы хотите открыть новый зоопарк. Это будет потрясающе. Но, будучи дешевым скейтбордом, вы хотите позволить себе только трехбуквенных животных (все знают, что стоимость животного пропорциональна длине его имени). Там идет ваша мечта заставить людей заплатить, чтобы увидеть elephant. Но вдруг у вас есть блестящая идея. Если вы просто поместите животных правильно в загон, вы можете создать оптическую иллюзию elephant! Вот вид сверху вашего нового "комплекса слонов":

elk
  eel
   pig
    hog
     ant

--------  (fence)
    ^
    | viewing direction

Ха-ха, эти доверчивые посетители!

Да, так работает восприятие.

Соревнование

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

ant ape asp ass bat bee boa cat cod cow 
dab dog eel elk emu fly fox gnu hog ide 
jay kea kob koi olm owl pig rat ray yak

Да, их более 30, но это хорошее круглое число.

При желании вы можете получить этот список в качестве входных данных (в любом приемлемом формате списка или строки, если он не был предварительно обработан). Вы, вероятно, захотите это сделать, если только чтение и обработка этого списка ввода не обходятся намного дороже, чем жесткое кодирование и сжатие на выбранном вами языке. Обратите внимание, что даже если вы возьмете список в качестве входных данных, вы можете предположить, что он всегда будет именно этим списком, поэтому, если ваш код опирается на переданный список длиной 30 элементов и не содержащий слова с z, это нормально.

Каждое слово может быть использовано несколько раз. Животные не могут быть отрезаны на концах, только частично скрыты другими животными. Так что oxэто не возможная строка, хотя у нас есть fox.

Вывод должен быть правдивым, если это возможно, и ложным в противном случае.

Вы можете написать программу или функцию, принимая ввод через STDIN (или ближайшую альтернативу), аргумент командной строки или аргумент функции и выводя результат через STDOUT (или ближайшую альтернативу), возвращаемое значение функции или параметр функции (out).

Ваш код должен обработать любой из тестовых случаев за несколько секунд.

Применяются стандартные правила .

Больше примеров

  • Любое одно- или двухбуквенное слово явно ложно.
  • Как и любое трехбуквенное слово, которого нет в приведенном выше списке.
  • Несмотря на то, что у нас есть gnuи rat, gnatэто ложно, так как нет способа расположить их так, чтобы вы видели только две буквы каждого (мы не хотим разделять животных на трети).

Несколько правдивых примеров:

pigment

    ant
  bee
 olm
pig
antioxidant

   fox
 koi  ide
ant     ant

Тестовые случаи

Большинство тестовых случаев были взяты из запуска эталонной реализации со словарем. Последние несколько «слов» были сгенерированы случайным образом и предназначены только для того, чтобы обеспечить достаточную эффективность представлений.

Truthy:

ant
owl
bass
pride
bobcat
peafowl
elephant
hedgehogs
crocodile
antidemocrat
aspidoganoidei
biodegradability
angioelephantiasis
propreantepenultimate
acategnukeaidabeleenaspcodcoidyakwakoasshogattkjaypigkobolcodidaskearaywelkwboaxbeeuflapaspoapemaassaaspeewoglmabiemuwjadogacagnuepigjaycownbatjaemuifoxkeaeekekeagratsseeluejdoghogaolmgpigbeaeelemulasphogjaydabemukgnunueifoasdoglrayyadogpewlayroassasslgnuaspyyakkbokeaodxilopgnuasppigkobelratelkolmakob
koigdgaspslycoyakehrdabowbatdkkeapogkobelrowlyarpidepetlfoxeboaiderbeefoxbgnuapeocowgiecowlkoieeltbategspemuideatdogbeeecatgeaoccattbbeassgnasolkeaflyelkaognubeeabrratoccolmobodoglyelraywelkoxantowleedrayflypeappigogatraoyakccpiganaaspkobabjaspkointantybjbeeanolmuijaylratojaynueidflyjarayabatmmpigtfly
eolmantjkobeeaorayogaowldfoxayeassapibatmflylyraelaspsseolmbelkkaoantlmufodasgnueantaidenthyakcodoxuepigodggnuantatlcatnuuelkpemucbapeeoiahdogplkowletbatdrayarayoaelkgrayodcatgkantewkobeljaybeeyfkobtbdabadoghbatfoxtflygaspdeidogtowlkeaolmyraelfleelejayehogowlccatoxeabiemkobpigolmdkobrcidekyakabboyidep

Falsy:

a
ox
ram
bear
koala
antelope
albatross
zookeeper
salamander
caterpillar
hippopotamus
koigdgaspslycoyakehrdabowbatdkkeapogkobelrowlyarpidepetlfoxeboaiderbeefoxbgnuapeocowgiecowlkoieeltbategspemuideatdogbeezcatgeaoccattbbeassgnasolkeaflyelkaognubeeabrratoccolmobodoglyelraywelkoxantowleedrayflypeappigogatraoyakccpiganaaspkobabjaspkointantybjbeeanolmuijaylratojaynueidflyjarayabatmmpigtfly
koigdgaspslycoyakehrdabowbatdkkeapogkobelrowlyarpidepetlfoxeboaiderbeefoxbgnuapeocowgiecowlkoieeltbategspemuideatdogbeeecatgeaoccattbbeassgnasolkeaflxelkaognubeeabrratoccolmobodoglyelraywelkoxantowleedrayflypeappigogatraoyakccpiganaaspkobabjaspkointantybjbeeanolmuijaylratojaynueidflyjarayabatmmpigtfly
beyeodpgspeclxlkbkaylldnceepkocbdmymsaogsowpbawbauaioluaaagaetdoaoialeoxaagspoelegflpylptylnolnatrjabaorkdteeydloiebbptatdtfdfgoodtbkoafmounbduaffcrfelcnawmxaskgaoenaattbaobgbgabnhkesbgaaaaotafkiiieatworginaeowaehuddegooaalowaoososaksahoimkulbtoadyyelkcmkacbuostadppcuglbnmotedfgfkoleldonknemomnmoutykg

Я все еще принимаю предложения для лучшего названия ...
Мартин Эндер

You may optionally receive this list as input- Значит ли это, что это не засчитывается в счет, в то время как жесткое программирование это будет?
Маринус

@marinus Да. Так что вы, вероятно, захотите использовать его как дополнительный ввод, если только чтение более чем одной строки на вводе не является действительно громоздким на вашем языке. (Я не хочу разрешать жесткое кодирование + «если вы это сделаете, вычтите его из своего счета», потому что тогда вы получите людей, которые жестко закодируют и сжимают его, что, по сути, даст им бонус к их счету.)
Мартин Эндер

Включает ли «параметр функции (выход) » параметры по ссылке ?
mynxomaτ

5
Не могу поверить, что пропустил комментарий «круглого числа» в песочнице. Позор вам, сэр! Вокруг этих частей 32 круглое число, а не 30. (И это не совсем попытка, чтобы вы пропустили имена для животных мужского пола - см. Свинья).
Питер Тейлор

Ответы:


7

Japt, 51 48 45 36 33 19 байт

Сохранено 9 байт благодаря @PeterTaylor

;!UeVrE"[$& ]" S² x

Проверьте это онлайн!

Принимает ввод в качестве строки для проверки, за которой следует список трехбуквенных слов, разделенных символом |. Примечание: это не работает в последней версии интерпретатора, поэтому, пожалуйста, используйте ссылку вместо копирования кода.

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

Основная идея состоит в том, чтобы взять входную строку и несколько раз заменить любое из 30 слов в ней двумя символами заполнения. Я использую пробел в качестве заполнителя. Также мы хотим заменить antin elephant, a  in ela   ,  ntin e   ntи т. Д. Итак, мы хотим изменить строку из 30 слов на регулярное выражение, соответствующее любой из этих комбинаций:

ant|ape|asp|...
Becomes:
[a ][n ][t ]|[a ][p ][e ]|[a ][s ][p ]|...

Мы можем сделать это довольно легко:

;VrE"[$& ]"
          // Implicit: V = "ant|ape|asp|..."
;         // Set the vars A-J to various values. E is set to "[a-z]".
VrE       // Take V and replace each lowercase letter with:
"[$& ]"   //  "[" + the char + " ]".

Однако это также приводит к нежелательному совпадению трех пробелов, что не влияет на результат и, таким образом, завершает рекурсивную замену. Мы можем обойти это, заменив совпадение двумя пробелами вместо трех:

Ue    S²  // Take U, and recursively replace matches of the regex with " ".repeat(2).

Вот основная демонстрация того, как и почему это работает (используя .вместо пробела):

First match at the end: 
eleant
ele..   (ant)
el..    (eel)
...     (elk)
..      (...)
true

First match at the beginning: 
antmua
..mua   (ant)
...a    (emu)
..a     (...)
..      (boa)
true

First match in the middle: 
cantay
c..ay   (ant)
..ay    (cat)
...     (jay)
..      (...)
true

Для истинных тестовых случаев это оставляет нам строку всех пробелов. Для ложных тест-кейсов у нас осталось несколько букв. Это может быть переведено в true / false следующим образом:

     x   // Trim all spaces off the ends of the resulting string.
!        // Take the logical NOT of the result.
         // Empty string -> true; non-empty string -> false.

И это все! Преимуществом этого метода является то, что даже самые большие тестовые случаи заканчиваются менее чем за 5 миллисекунд. ( Проверено здесь )


« Это не легко сделать с одним регулярным выражением » - что не так с (?!,,,)?
Питер Тейлор

@PeterTaylor facepalm Спасибо, это экономит около 10 байтов ...
ETHproductions

1
@PeterTaylor Я нашел гораздо более короткий метод: просто замените его двумя пробелами вместо трех. До 19 байт!
ETHproductions

Еще один момент лицевой стороны лица ?
Нил

@ Нил Да, довольно. Я думал о том, чтобы попробовать два пробела вместо трех, но я не понимал, что это сработает так хорошо до сегодняшнего утра, когда продумывал множество альтернативных стратегий.
ETHproductions

3

GNU grep, 62 + 1 = 63 байта

^(((.+)(?=.*!\3))*(...)(?=.*\4!)((.+)(?=.*\6!))*([^qvz]\B)?)+ 

Это требует Pопции. Предполагается, что вводом будет синтезируемое животное, за которым следует пробел, за которым следует список трехбуквенных животных, открытых, закрытых и разделенных восклицательными знаками. Пример использования (при условии, что программа сохранена как zoo):

> grep -Pf zoo
hippopotamus !ant!ape!asp!ass!bat!bee!boa!cat!cod!cow!dab!dog!eel!elk!emu!fly!fox!gnu!hog!ide!jay!kea!kob!koi!olm!owl!pig!rat!ray!yak!

Для истинного ввода, строка ввода отражается обратно. Для ложного ввода нет вывода.

Спасибо Мартину за то, что он нашел ошибку и предупредил меня о существовании \Bслова «non-border».


Разве у grep нет границ без слов, \Bчтобы вы могли избавиться от последнего взгляда? (Если этого не произойдет, переключение на Retina позволит сэкономить несколько байтов. На самом деле я думаю, что это все равно сохранит байт, потому что ему не нужна Pопция.)
Мартин Эндер

Сейчас я не могу проверить с помощью grep, но справится ли это с большими ложными контрольными случаями за несколько секунд? В Retina откат занимает довольно много времени.
Мартин Эндер

1
@ MartinBüttner За последние пару ложных случаев он сдался и распечатался grep: exceeded PCRE's backtracking limit.
feersum

1
Использование GNU для решения этой проблемы кажется весьма уместным.
Antti29

2

ES6, 122 121 119 104 байта

Я разработал, как это сделать, до ответа ETHproduction, но не мог придумать, как справиться с ,,,проблемой *, поэтому, естественно, когда я увидел комментарий Питера Тейлора, все стало ясно. Тогда ETHproductions удалось найти лучший способ решения проблемы, который помог бы сэкономить 15 байт.

Ввод - это целевое слово и массив слов животных.

(s,a)=>[...s].map(_=>s=s.replace(RegExp(a.map(a=>a.replace(/./g,"[&$&]")).join`|`),'&&'))&&!/\w/.test(s)

Редактировать: 1 байт сохранен 3 байта благодаря @ETHproductions.

* За исключением того, что я использовал & s, потому что это выглядит лучше в моем replace.


Очень хорошо! Будет ли работать любая из этих вещей: 1) использование (`(?!&&&)(${a.map...})`)в качестве строки, 2) удаление скобок после этого, 3) использование eval`/(?!&&&).../` ?
ETHproductions

@ETHproductions Я сделал ошибку, удалив внешние ()s, которые не работают; с этим ()он работает и экономит мне байт. evalтакже нуждается в ()s, так что он больше ничего не сохраняет, извините.
Нил

Я думаю, у вас также есть лишняя пара круглых скобок a.replace(...).
ETHproductions

Вы можете сохранить связку: s=s.replace(RegExp(a.map(a=>a.replace(/./g,"[&$&]")).join`|`),'&&')замена двух символов вместо трех исключает возможность застрять, заменяя одни и те же три символа снова и снова.
ETHproductions

0

JS ES6, 77 байт

s=>/^(((.+)(?=.*!\3))*(...)(?=.*\4!)((.+)(?=.*\6!))*([^qvz][^\b])?)+/.test(s)

(это анонимный фн)

Ввод такой же, как в приведенном выше примере с grep


Если вы принимаете ввод с помощью prompt()Разве вы не должны использовать alert()? (Или просто сделайте это функцией.)
Нил

@ Нейл спасибо, я использовал скоро. fn
username.ak
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.