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


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.

Висновок повинен бути truthy , якщо це можливо, і falsy інакше.

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

Ваш код повинен обробити будь-який з тестових випадків за кілька секунд.

Діють стандартні правила .

Більше прикладів

  • Будь-яке одно- або двобуквене слово очевидно хибне.
  • Так само будь-яке трибуквене слово, якого немає у наведеному вище списку.
  • Хоча у нас є gnuі rat, gnatце falsy , так як немає ніякого способу , щоб розташувати їх так , що ви бачите тільки дві літери кожного (ми не хочемо , щоб скоротити тварина в третину).

Деякі приклади:

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

Фальсі:

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

Я все ще беру пропозиції щодо кращого титулу ...
Мартін Ендер

You may optionally receive this list as input- це означає, що вона не зараховується до балу, тоді як жорстке кодування це було б?
marinus

@marinus Так. Таким чином, ви, ймовірно, захочете взяти це як додатковий вклад, якщо тільки читання декількох рядків при введенні не є справді громіздким вашою мовою на вибір. (Я не хочу дозволити жорстке кодування + "якщо ви це зробите, відніміть його від вашої оцінки", тому що тоді ви отримаєте людей, які твердо кодують і стискають їх, що, по суті, дасть їм бонус за їх рахунок.)
Мартін Ендер

Чи включає параметр " функція (вихід) " параметри за посиланням ?
mınxomaτ

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

Для справжніх тестів це залишає нам ряд з усіх пробілів. У фальшивих тестових випадках у суміші залишилось кілька букв. Це може бути переведено на справжнє / хибне так:

     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

Ще один момент обличчя ?
Ніл

@Neil Так, дуже багато. Я думав про те, щоб спробувати два простори замість трьох, але не зрозумів, що це буде так добре до цього ранку, коли продумаю багато альтернативних стратегій.
ETHproductions

3

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

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

Для цього потрібен Pваріант. Очікується, що тварина буде синтезованим, а потім пробілом, а потім списком 3-літерних тварин, відкритих, закритих та обмежених знаками оклику. Приклад використання (якщо програма збережена як 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слова без меж.


У грепу немає меж слова, \Bщоб ви могли позбутися останнього лукахеда? (Якщо цього не відбудеться, перехід на Retina заощадив би кілька байт. Насправді я думаю, що це все-таки збереже байт, тому що він не потребує цього Pваріанту.)
Martin Ender

Я зараз не можу перевірити грепом, але чи справді це справляється з великими хибними тестовими справами за кілька секунд? У 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)

(це анонімний fn)

Вхід такий самий, як у наведеному вище прикладі grep


Якщо ви приймаєте дані, prompt()чи не слід виводити, використовуючи alert()? (Або просто зробіть це функцією.)
Ніл

@Neil спасибі, я використав anon. fn
username.ak
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.