Betrüger im Zoo

42

Sie möchten einen neuen Zoo eröffnen. Es wird großartig. Aber weil Sie so billig sind, möchten Sie sich nur Tiere mit drei Buchstaben leisten (jeder weiß, dass die Kosten eines Tieres proportional zur Länge seines Namens sind). Ihr Traum geht dahin, die Leute dafür bezahlen zu lassen, eine zu sehen elephant. Aber plötzlich hast du eine geniale Idee. Wenn Sie die Tiere nur richtig in den Stift legen, können Sie die optische Täuschung eines elephant! Hier ist eine Ansicht von oben auf Ihre neue "Elefantenverbindung":

elk
  eel
   pig
    hog
     ant

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

Haha, diese leichtgläubigen Besucher!

Ja, so funktioniert Wahrnehmung.

Die Herausforderung

Bestimmen Sie, ob ein nicht leeres Wort, das nur aus englischen Kleinbuchstaben besteht, aus der Überlappung der folgenden 30 tierischen Wörter mit drei Buchstaben gebildet werden kann:

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

Ja, es gibt mehr als 30, aber das ist eine schöne runde Zahl.

Optional können Sie diese Liste als Eingabe erhalten (in jedem vernünftigen Listen- oder Zeichenfolgeformat, sofern es nicht vorverarbeitet ist). Möglicherweise möchten Sie dies tun, es sei denn, das Lesen und Verarbeiten dieser Eingabeliste ist viel teurer als das Hardcodieren und Komprimieren in der Sprache Ihrer Wahl. Beachten Sie, dass Sie, selbst wenn Sie die Liste als Eingabe verwenden, davon ausgehen können, dass es sich immer um genau diese Liste handelt. Wenn Sie also davon ausgehen, dass die übergebene Liste 30 Elemente lang ist und kein Wort mit enthält z, ist das in Ordnung.

Jedes Wort kann mehrfach verwendet werden. Tiere können an den Enden nicht abgeschnitten werden, sondern nur teilweise von anderen Tieren verdeckt werden. Also oxist keine mögliche Zeichenfolge, obwohl wir haben fox.

Die Ausgabe sollte wahr sein, wenn dies möglich ist, und falsch, wenn dies nicht möglich ist .

Sie können ein Programm oder eine Funktion schreiben, indem Sie eine Eingabe über STDIN (oder die nächstgelegene Alternative), ein Befehlszeilenargument oder ein Funktionsargument vornehmen und das Ergebnis über STDOUT (oder die nächstgelegene Alternative), einen Funktionsrückgabewert oder einen Funktionsparameter (out) ausgeben.

Ihr Code sollte in wenigen Sekunden alle Testfälle verarbeiten.

Es gelten die Standardregeln für .

Mehr Beispiele

  • Jedes ein- oder zweistellige Wort ist offensichtlich falsch.
  • So ist jedes Wort mit drei Buchstaben, das nicht in der obigen Liste ist.
  • Auch wenn wir gnuund haben rat, gnatist das falsch, da es keine Möglichkeit gibt, sie so anzuordnen, dass Sie nur zwei Buchstaben von jedem sehen (wir wollen Tiere nicht in Drittel schneiden).

Einige wahrheitsgemäße Beispiele:

pigment

    ant
  bee
 olm
pig
antioxidant

   fox
 koi  ide
ant     ant

Testfälle

Die meisten Testfälle stammen aus der Ausführung einer Referenzimplementierung für ein Wörterbuch. Die letzten "Wörter" wurden zufällig generiert und sind nur dazu da, um sicherzustellen, dass die Einreichungen ausreichend effizient sind.

Wahrheit:

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

Falsch:

a
ox
ram
bear
koala
antelope
albatross
zookeeper
salamander
caterpillar
hippopotamus
koigdgaspslycoyakehrdabowbatdkkeapogkobelrowlyarpidepetlfoxeboaiderbeefoxbgnuapeocowgiecowlkoieeltbategspemuideatdogbeezcatgeaoccattbbeassgnasolkeaflyelkaognubeeabrratoccolmobodoglyelraywelkoxantowleedrayflypeappigogatraoyakccpiganaaspkobabjaspkointantybjbeeanolmuijaylratojaynueidflyjarayabatmmpigtfly
koigdgaspslycoyakehrdabowbatdkkeapogkobelrowlyarpidepetlfoxeboaiderbeefoxbgnuapeocowgiecowlkoieeltbategspemuideatdogbeeecatgeaoccattbbeassgnasolkeaflxelkaognubeeabrratoccolmobodoglyelraywelkoxantowleedrayflypeappigogatraoyakccpiganaaspkobabjaspkointantybjbeeanolmuijaylratojaynueidflyjarayabatmmpigtfly
beyeodpgspeclxlkbkaylldnceepkocbdmymsaogsowpbawbauaioluaaagaetdoaoialeoxaagspoelegflpylptylnolnatrjabaorkdteeydloiebbptatdtfdfgoodtbkoafmounbduaffcrfelcnawmxaskgaoenaattbaobgbgabnhkesbgaaaaotafkiiieatworginaeowaehuddegooaalowaoososaksahoimkulbtoadyyelkcmkacbuostadppcuglbnmotedfgfkoleldonknemomnmoutykg
Martin Ender
quelle
Ich mache immer noch Vorschläge für einen besseren Titel ...
Martin Ender
You may optionally receive this list as input- Bedeutet das, dass es nicht für die Punktzahl zählt, wohingegen es hart codiert würde?
Marinus
@marinus Ja. Daher möchten Sie es wahrscheinlich als zusätzliche Eingabe verwenden, es sei denn, das Lesen von mehr als einer Zeichenfolge bei der Eingabe ist in der Sprache Ihrer Wahl sehr umständlich. (Ich möchte keine Hardcodierung zulassen + "Wenn Sie dies tun, subtrahieren Sie es von Ihrer Punktzahl", weil dann die Leute es hardcodieren und komprimieren, was ihnen im Wesentlichen einen Bonus auf ihre Punktzahl geben würde.)
Martin Ender
Umfasst " Funktionsparameter (Out-Parameter) " Parameter als Referenz ?
Mittwoch,
5
Ich kann nicht glauben, dass ich den Kommentar "Runde Nummer" im Sandkasten verpasst habe. Schande über dich, Sir! Um diese Teile herum ist 32 eine runde Zahl, nicht 30. (Und es ist nicht ganz klar, dass Sie Namen für männliche Tiere ausgelassen haben - siehe Schwein).
Peter Taylor

Antworten:

7

Japt, 51 48 45 36 33 19 Bytes

9 Bytes dank @PeterTaylor gespart

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

Online testen!

Nimmt die Eingabe als zu testende Zeichenfolge, gefolgt von der Liste der Wörter mit drei Buchstaben, die durch getrennt sind |. Hinweis: Dies funktioniert in der neuesten Version des Interpreters nicht. Verwenden Sie daher den Link, anstatt den Code zu kopieren.

Wie es funktioniert

Die Grundidee ist, die Eingabezeichenfolge zu nehmen und jedes der 30 Wörter durch zwei Füllzeichen zu ersetzen. Ich benutze ein Leerzeichen als Füllzeichen. Außerdem möchten wir das antIn elephant, das a  In ela   , das  ntIn e   ntusw. ersetzen. Wir möchten also die 30-Wort-Zeichenfolge in eine reguläre Zeichenfolge ändern, die mit einer der folgenden Kombinationen übereinstimmt:

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

Wir können das ziemlich einfach machen:

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

Dies hat jedoch den unerwünschten Effekt, dass auch drei Leerzeichen übereinstimmen, was sich nicht auf das Ergebnis auswirkt und somit die rekursive Ersetzung beendet. Wir können das umgehen, indem wir das Match durch zwei statt drei Leerzeichen ersetzen:

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

Hier ist eine grundlegende Demonstration, wie und warum dies funktioniert ( .anstelle eines Leerzeichens):

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

Für wahrheitsgemäße Testfälle bleibt uns eine Reihe von Leerzeichen übrig. Für falsche Testfälle haben wir noch ein paar Buchstaben im Mix. Dies kann folgendermaßen in wahr / falsch übersetzt werden:

     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.

Und das war's auch schon! Ein Vorteil dieser Methode ist, dass selbst die größten Testfälle in weniger als 5 Millisekunden abgeschlossen sind. (Hier getestet )

ETHproductions
quelle
" Mit Regex allein ist das nicht einfach " - was ist daran falsch (?!,,,)?
Peter Taylor
@PeterTaylor facepalm Danke, das etwa 10 Bytes speichert ...
ETHproductions
1
@PeterTaylor Ich habe eine viel kürzere Methode gefunden: einfach durch zwei statt drei Leerzeichen ersetzen. Bis zu 19 Bytes!
ETHproductions
Noch ein Facepalm- Moment?
Neil
@ Neil Yep, so ziemlich. Ich hatte darüber nachgedacht, zwei statt drei Felder zu versuchen, aber ich wusste nicht, dass es so gut funktionieren würde, bis ich heute Morgen viele alternative Strategien durchdacht hatte.
ETHproductions
3

GNU grep, 62 + 1 = 63 Bytes

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

Dies erfordert die POption. Es wird erwartet, dass die Eingabe das zu synthetisierende Tier ist, gefolgt von einem Leerzeichen, gefolgt von einer Liste von Tieren mit drei Buchstaben, die geöffnet, geschlossen und durch Ausrufezeichen begrenzt sind. Anwendungsbeispiel (vorausgesetzt, das Programm wird gespeichert als 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!

Bei einer echten Eingabe wird die Eingabezeile zurückgemeldet. Bei einer falschen Eingabe gibt es keine Ausgabe.

Vielen Dank an Martin, der einen Fehler entdeckt und mich auf das Vorhandensein eines \BWortes ohne Grenzen aufmerksam gemacht hat.

Feersum
quelle
Hat grep keine Nicht-Wort-Grenzen, \Bso dass Sie den letzten Lookahead loswerden können? (Wenn nicht, würde das Umschalten auf Retina ein paar Bytes sparen. Eigentlich würde es sowieso ein Byte sparen, weil es die POption nicht benötigt .)
Martin Ender
Ich kann momentan nicht mit grep testen, aber kann dies die großen falschen Testfälle tatsächlich in wenigen Sekunden bewältigen? In Retina dauert das Zurückverfolgen eine ganze Weile.
Martin Ender
1
@ MartinBüttner Für die letzten paar gefälschten Fälle hat es tatsächlich aufgegeben und gedruckt grep: exceeded PCRE's backtracking limit.
Feersum
1
Die Verwendung von GNU zur Lösung dieses Problems scheint sehr angebracht.
Antti29
2

ES6, 122 121 119 104 Bytes

Ich hatte, soweit die Antwort von ETHproduction ausschlaggebend war, überlegt, wie ich mit dem ,,,Problem umgehen sollte. Als ich also Peter Taylors Kommentar sah, wurde mir natürlich alles klar. Dann hat ETHproductions es geschafft, eine bessere Lösung für das Problem zu finden, das 15 Bytes einspart.

Die Eingabe ist das Zielwort und eine Reihe von Tierwörtern.

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

Bearbeiten: 1 Byte 3 Byte dank @ETHproductions gespeichert.

* Außer ich habe & s benutzt, weil es in meinem besser aussieht replace.

Neil
quelle
Sehr schön! Würde eines dieser Dinge funktionieren: 1) Verwenden (`(?!&&&)(${a.map...})`)als String, 2) Entfernen der Klammern danach, 3) Verwenden eval`/(?!&&&).../` ?
ETHproductions
@ETHproductions Ich habe den Fehler gemacht, das äußere ()s zu entfernen, was nicht funktioniert. mit dem ()klappt es und spart mir ein byte. evalbraucht auch das ()s damit es nichts weiter speichert, sorry.
Neil
Ich denke, Sie haben auch ein zusätzliches Paar Klammern a.replace(...).
ETHproductions
Sie können eine Menge sparen: Durch s=s.replace(RegExp(a.map(a=>a.replace(/./g,"[&$&]")).join`|`),'&&')Ersetzen mit zwei anstelle von drei Zeichen wird die Möglichkeit beseitigt, dass Sie nicht mehr weiterkommen und dieselben drei Zeichen immer wieder ersetzen.
ETHproductions
0

JS ES6, 77 Bytes

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

(das ist anonym fn)

Die Eingabe entspricht der obigen Beispieleingabe für grep

Benutzername.ak
quelle
Wenn Sie Eingaben mit machen, prompt()sollten Sie dann nicht mit ausgeben alert()? (Alternativ können Sie dies auch zu einer Funktion machen.)
Neil
@Neil danke, ich habe anon benutzt. fn
username.ak