Oszuści w zoo

42

Chcesz otworzyć nowe zoo. To będzie niesamowite. Ale będąc tanią łyżwą, którą jesteś, chcesz pozwolić sobie tylko na trzyliterowe zwierzęta (wszyscy wiedzą, że koszt zwierzęcia jest proporcjonalny do długości jego nazwy). Istnieje marzenie, aby ludzie płacili za oglądanie elephant. Ale nagle masz genialny pomysł. Jeśli po prostu prawidłowo umieścisz zwierzęta we zagrodzie, możesz stworzyć złudzenie optyczne elephant! Oto widok z góry nowego „związku słoni”:

elk
  eel
   pig
    hog
     ant

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

Haha, ci łatwowierni goście!

Tak, tak działa percepcja.

Wyzwanie

Biorąc pod uwagę niepuste słowo składające się tylko z małych angielskich liter, określ, czy można je utworzyć, nakładając następujące 30 trzyliterowe słowa zwierząt:

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

Tak, jest ich ponad 30, ale to ładna okrągła liczba.

Opcjonalnie możesz otrzymać tę listę jako dane wejściowe (w dowolnym rozsądnym formacie listy lub ciągu, o ile nie jest ona wstępnie przetworzona). Prawdopodobnie zechcesz to zrobić, chyba że czytanie i przetwarzanie tej listy danych wejściowych jest znacznie droższe niż kodowanie i kompresowanie jej w wybranym języku. Zauważ, że nawet jeśli weźmiesz listę jako dane wejściowe, możesz założyć, że zawsze będzie to dokładnie ta lista, więc jeśli twój kod opiera się na przekazywanej liście mającej 30 elementów i nie zawierającej słowa z, to jest w porządku.

Każde słowo może być użyte wiele razy. Zwierzęta nie mogą być odcięte na końcach, tylko częściowo ukryte przez inne zwierzęta. Więc oxnie jest możliwy ciąg, nawet jeśli mamy fox.

Dane wyjściowe powinny być zgodne z prawdą, jeśli jest to możliwe, a fałsz w przeciwnym razie.

Możesz napisać program lub funkcję, pobierając dane wejściowe przez STDIN (lub najbliższą alternatywę), argument wiersza poleceń lub argument funkcji i wypisując wynik przez STDOUT (lub najbliższą alternatywę), wartość zwracaną funkcji lub parametr funkcji (wyjściowej).

Twój kod powinien obsłużyć dowolny z przypadków testowych w ciągu kilku sekund.

Obowiązują standardowe zasady .

Więcej przykładów

  • Każde jedno- lub dwuliterowe słowo jest oczywiście fałszem.
  • Podobnie jak każde trzyliterowe słowo, którego nie ma na powyższej liście.
  • Nawet jeśli mamy gnui rat, gnatjest falsy ponieważ nie ma sposobu, aby zorganizować je tak, że widać tylko dwa listy każda (nie chcemy wyciąć zwierząt na trzy części).

Kilka prawdziwych przykładów:

pigment

    ant
  bee
 olm
pig
antioxidant

   fox
 koi  ide
ant     ant

Przypadki testowe

Większość przypadków testowych została zaczerpnięta z uruchomienia implementacji referencyjnej dla słownika. Ostatnie kilka „słów” zostało wygenerowanych losowo i są one tylko po to, aby zapewnić wystarczającą wydajność przesyłania.

Prawda:

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
Martin Ender
źródło
Nadal szukam propozycji lepszego tytułu ...
Martin Ender
You may optionally receive this list as input- czy to oznacza, że ​​nie liczy się on do partytury, podczas gdy kodowanie byłoby trudne?
marinus
@marinus Tak. Prawdopodobnie zechcesz to potraktować jako dodatkowe dane wejściowe, chyba że czytanie więcej niż jednego ciągu wejściowego jest naprawdę kłopotliwe w wybranym języku. (Nie chcę zezwalać na twarde kodowanie + „jeśli to zrobisz, odejmij to od swojego wyniku”, ponieważ wtedy dostaniesz ludzi zakodowanych na stałe i kompresujących, co w zasadzie dałoby im premię do ich wyniku).
Martin Ender
Czy „parametr funkcji (wyjściowej) ” obejmuje parametry przez odniesienie ?
mınxomaτ
5
Nie mogę uwierzyć, że przeoczyłem komentarz do „okrągłej liczby” w piaskownicy. Wstydź się panu! Wokół tych części 32 jest okrągła liczba, a nie 30. (I nie do końca próbujesz pominąć nazwy dla samców - patrz wieprz).
Peter Taylor

Odpowiedzi:

7

Japt, 51 48 45 36 33 19 bajtów

Zaoszczędź 9 bajtów dzięki @PeterTaylor

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

Przetestuj online!

Pobiera dane wejściowe jako ciąg znaków do przetestowania, a następnie listę słów trzyliterowych, rozdzielonych znakiem |. Uwaga: nie działa to w najnowszej wersji interpretera, więc użyj linku zamiast kopiowania i wklejania kodu.

Jak to działa

Podstawową ideą jest pobranie ciągu wejściowego i wielokrotne zastępowanie dowolnego z 30 zawartych w nim słów dwoma znakami wypełniającymi. Używam spacji jako znaku wypełniającego. Chcemy również zastąpić antin elephant, a  in ela   ,  ntin e   ntitp. Więc chcemy zmienić 30-wyrazowy ciąg na wyrażenie regularne pasujące do dowolnej z tych kombinacji:

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

Możemy to zrobić dość łatwo:

;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 + " ]".

Ma to jednak niepożądany efekt dopasowania również trzech spacji, co nie ma wpływu na wynik, a zatem kończy rekurencyjną zamianę. Możemy to obejść, zastępując mecz dwoma spacjami zamiast trzema:

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

Oto podstawowa demonstracja tego, jak i dlaczego to działa (użycie .zamiast spacji):

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

W przypadku prawdziwych przypadków testowych pozostawia nam to ciąg wszystkich spacji. W przypadku fałszywych przypadków testowych pozostało kilka liter w miksie. Można to przetłumaczyć na prawda / fałsz tak:

     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.

I o to chodzi! Zaletą tej metody jest to, że nawet największe przypadki testowe kończą się w czasie poniżej 5 milisekund. ( Testowane tutaj )

ETHprodukcje
źródło
Nie jest to łatwe z samym wyrażeniem regularnym ” - co jest nie tak (?!,,,)?
Peter Taylor
@PeterTaylor facepalm Dzięki, że oszczędza około 10 bajtów ...
ETHproductions
1
@PeterTaylor Znalazłem znacznie krótszą metodę: po prostu zamień na dwie spacje zamiast trzech. Do 19 bajtów!
ETHproductions
Kolejny moment na twarz ?
Neil
@ Nee Yep, właściwie. Myślałem o wypróbowaniu dwóch spacji zamiast trzech, ale nie zdawałem sobie sprawy, że to zadziała tak dobrze aż do dzisiejszego ranka, kiedy będę rozważał wiele alternatywnych strategii.
ETHproductions
3

GNU grep, 62 + 1 = 63 bajty

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

To wymaga Popcji. Dane wejściowe mają być zwierzęciem, które ma zostać zsyntetyzowane, a następnie spacją, a następnie listą 3-literowych zwierząt otwartych, zamkniętych i ograniczonych wykrzyknikami. Przykładowe użycie (przy założeniu, że program zostanie zapisany jako 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!

Dla prawdziwego wejścia linia wejściowa jest wyświetlana z powrotem. W przypadku fałszywych danych wejściowych nie ma danych wyjściowych.

Podziękowania dla Martina za wykrycie błędu i powiadomienie mnie o istnieniu \Bsłowa „bez granic”.

feersum
źródło
Czy grep nie ma granic innych niż słowa \B, abyś mógł pozbyć się ostatniego spojrzenia? (Jeśli nie, przełączanie do siatkówki byłoby zaoszczędzić kilka bajtów Właściwie myślę, że byłoby to zapisać bajt w każdym razie, bo nie potrzebuje. POpcji).
Marcina, Ender
Nie mogę teraz testować za pomocą grep, ale czy to naprawdę obsługuje duże przypadki testów fałszowania w ciągu kilku sekund? Cofanie w Retinie zajmuje sporo czasu.
Martin Ender
1
@ MartinBüttner W przypadku ostatnich kilku przypadków fałszerstwa faktycznie się poddał i wydrukował grep: exceeded PCRE's backtracking limit.
feersum
1
Używanie GNU do rozwiązania tego problemu wydaje się wysoce właściwe.
Antti29,
2

ES6, 122 121 119 104 bajtów

Nauczyłem się, jak to zrobić, jeśli chodzi o odpowiedź ETHproduction, ale nie mogłem wymyślić, jak poradzić sobie z ,,,* problemem, więc naturalnie, gdy zobaczyłem komentarz Petera Taylora, wszystko stało się jasne. Następnie ETHproductions udało się znaleźć lepszy sposób na rozwiązanie problemu, który pomaga zaoszczędzić 15 bajtów.

Dane wejściowe to słowo docelowe i tablica słów zwierząt.

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

Edycja: Zapisano 1 bajt 3 bajty dzięki @ETHproductions.

* Tyle że użyłem & s, ponieważ wygląda ładniej w moim replace.

Neil
źródło
Bardzo dobrze! Czy którakolwiek z tych rzeczy działałaby: 1) użycie (`(?!&&&)(${a.map...})`)jako ciągu, 2) usunięcie nawiasów po wykonaniu tego, 3) użycie eval`/(?!&&&).../` ?
ETHprodukcje
@ETHproductions Popełniłem błąd, usuwając elementy zewnętrzne, ()które nie działają; dzięki ()temu działa i oszczędza mi bajt. evalpotrzebuje również ()s, więc nie oszczędza nic więcej, przepraszam.
Neil
Myślę, że masz też dodatkową parę nawiasów a.replace(...).
ETHproductions
Możesz zapisać kilka: s=s.replace(RegExp(a.map(a=>a.replace(/./g,"[&$&]")).join`|`),'&&')Zastąpienie dwoma znakami zamiast trzema usuwa możliwość utknięcia, zastępując te same trzy znaki w kółko.
ETHproductions
0

JS ES6, 77 bajtów

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

(to anonimowy fn)

Dane wejściowe są takie same jak w powyższym przykładzie grep

nazwa_użytkownika.ak
źródło
Jeśli przyjmujesz dane wejściowe, prompt()czy nie powinieneś używać danych wyjściowych alert()? (Ewentualnie po prostu włącz tę funkcję.)
Neil
@ Nee dzięki, użyłem anona. fn
nazwa_użytkownika.ak