Imposters au zoo

42

Vous voulez ouvrir un nouveau zoo. Ça va être incroyable. Mais étant le radin que vous êtes, vous ne voulez vous permettre que des animaux à trois lettres (tout le monde sait que le coût d'un animal est proportionnel à la longueur de son nom). Voilà votre rêve de faire payer les gens pour voir un elephant. Mais tout à coup, vous avez une idée brillante. Si vous placez les animaux correctement dans le stylo, vous pouvez créer l'illusion d'optique d'un elephant! Voici une vue de dessus de votre nouveau "composé d'éléphant":

elk
  eel
   pig
    hog
     ant

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

Haha, ces visiteurs crédules!

Oui, c'est ainsi que fonctionne la perception.

Le défi

À partir d'un mot non vide composé uniquement de lettres anglaises minuscules, déterminez s'il peut être formé en superposant les 30 mots animaux suivants de trois lettres:

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

Oui, il y en a plus de 30, mais c'est un bon chiffre rond.

Vous pouvez éventuellement recevoir cette liste en entrée (dans n'importe quelle liste ou format de chaîne raisonnable, tant qu'elle n'est pas pré-traitée). Vous voudrez probablement le faire, à moins que la lecture et le traitement de cette liste d’entrée coûtent beaucoup plus cher que le codage en dur et la compression dans la langue de votre choix. Notez que même si vous prenez la liste en entrée, vous pouvez supposer que ce sera toujours cette liste. Si votre code repose sur une liste de 30 éléments et ne contient pas de mot z, c'est correct.

Chaque mot peut être utilisé plusieurs fois. Les animaux ne peuvent pas être coupés aux extrémités, ils ne sont que partiellement cachés par d'autres animaux. Donc, ce oxn'est pas une chaîne possible, même si nous avons fox.

La sortie devrait être la vérité si cela est possible, et la fausseté sinon.

Vous pouvez écrire un programme ou une fonction en prenant l’entrée via STDIN (ou l’alternative la plus proche), un argument de ligne de commande ou une argumentation de fonction et en générant le résultat via STDOUT (ou l’alternative la plus proche), une valeur de retour de fonction ou un paramètre de fonction (out).

Votre code devrait gérer n'importe lequel des cas de test en quelques secondes.

Les règles standard de s'appliquent.

Plus d'exemples

  • Tout mot d'une ou deux lettres est évidemment faux.
  • Il en va de même des mots de trois lettres qui ne figurent pas dans la liste ci-dessus.
  • Bien que nous ayons gnuet rat, gnatest falsy car il n'y a aucun moyen de les organiser de telle sorte que vous ne voyez deux lettres de chaque (nous ne voulons pas couper les animaux en tiers).

Quelques exemples de vérité:

pigment

    ant
  bee
 olm
pig
antioxidant

   fox
 koi  ide
ant     ant

Cas de test

La plupart des cas de test provenaient de l'exécution d'une implémentation de référence sur un dictionnaire. Les derniers "mots" ont été générés de manière aléatoire et sont simplement là pour assurer que les soumissions sont suffisamment efficaces.

Vérité

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

Fausseté:

a
ox
ram
bear
koala
antelope
albatross
zookeeper
salamander
caterpillar
hippopotamus
koigdgaspslycoyakehrdabowbatdkkeapogkobelrowlyarpidepetlfoxeboaiderbeefoxbgnuapeocowgiecowlkoieeltbategspemuideatdogbeezcatgeaoccattbbeassgnasolkeaflyelkaognubeeabrratoccolmobodoglyelraywelkoxantowleedrayflypeappigogatraoyakccpiganaaspkobabjaspkointantybjbeeanolmuijaylratojaynueidflyjarayabatmmpigtfly
koigdgaspslycoyakehrdabowbatdkkeapogkobelrowlyarpidepetlfoxeboaiderbeefoxbgnuapeocowgiecowlkoieeltbategspemuideatdogbeeecatgeaoccattbbeassgnasolkeaflxelkaognubeeabrratoccolmobodoglyelraywelkoxantowleedrayflypeappigogatraoyakccpiganaaspkobabjaspkointantybjbeeanolmuijaylratojaynueidflyjarayabatmmpigtfly
beyeodpgspeclxlkbkaylldnceepkocbdmymsaogsowpbawbauaioluaaagaetdoaoialeoxaagspoelegflpylptylnolnatrjabaorkdteeydloiebbptatdtfdfgoodtbkoafmounbduaffcrfelcnawmxaskgaoenaattbaobgbgabnhkesbgaaaaotafkiiieatworginaeowaehuddegooaalowaoososaksahoimkulbtoadyyelkcmkacbuostadppcuglbnmotedfgfkoleldonknemomnmoutykg
Martin Ender
la source
Je prends toujours des suggestions pour un meilleur titre ...
Martin Ender
You may optionally receive this list as input- Cela signifie-t-il qu'il ne compte pas dans le score, alors que coder en dur le serait?
marinus
@marinus Oui. Ainsi , vous aurez probablement voulez prendre comme entrée supplémentaire, à moins que la lecture de plus d'une corde à l' entrée est vraiment lourd dans votre langue de choix. (Je ne veux pas autoriser le codage en dur + "si vous le faites, soustrayez-le de votre score", car alors vous obtiendrez un codage en dur et une compression, ce qui donnerait essentiellement un bonus à leur score.)
Martin Ender
Le paramètre " fonction (sortie) " inclut-il des paramètres par référence ?
Mınxomaτ
5
Je ne peux pas croire que j'ai raté le commentaire "numéro rond" dans le bac à sable. Honte à vous, monsieur! 32 est un chiffre rond et non pas un chiffre rond.
Peter Taylor

Réponses:

7

Japt, 51 48 45 36 33 19 octets

9 octets sauvés grâce à @PeterTaylor

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

Testez-le en ligne!

Prend l'entrée en tant que chaîne à tester, suivie de la liste des mots de trois lettres, délimités par |. Remarque: cela ne fonctionne pas dans la dernière version de l'interpréteur, utilisez donc le lien au lieu de copier-coller le code.

Comment ça marche

L'idée de base est de prendre la chaîne en entrée et de remplacer à plusieurs reprises l'un des 30 mots qu'elle contient par deux caractères de remplissage. J'utilise un espace comme caractère de remplissage. Nous voulons également remplacer les caractères antin elephant, a  in ela   ,  ntin e   nt, etc. Nous souhaitons donc modifier la chaîne de 30 mots en une expression rationnelle qui correspond à l'une de ces combinaisons:

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

Nous pouvons le faire assez facilement:

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

Cependant, cela a pour effet indésirable de faire correspondre également trois espaces, ce qui n'a aucun effet sur le résultat et met donc fin au remplacement récursif. Nous pouvons contourner ce problème en remplaçant le match par deux espaces au lieu de trois:

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

Voici une démonstration de base de comment et pourquoi cela fonctionne (en utilisant .à la place d'un espace):

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

Pour les cas de test de vérité, cela nous laisse avec une chaîne de tous les espaces. Pour les cas de tests de fausseté, nous avons quelques lettres dans le mélange. Ceci peut être traduit en vrai / faux comme ceci:

     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.

Et c'est à peu près tout! Un avantage de cette méthode est que même les cas de test les plus volumineux se terminent en moins de 5 millisecondes. ( Testé ici )

ETHproductions
la source
" Ce n'est pas chose facile avec regex seul " - quel est le problème (?!,,,)?
Peter Taylor le
@PeterTaylor facepalm Merci, cela économise environ 10 octets ...
ETHproductions
1
@ PeterTaylor J'ai trouvé une méthode beaucoup plus courte: remplacez simplement par deux espaces au lieu de trois. Jusqu'à 19 octets!
ETHproductions
Un autre moment facepalm alors?
Neil
@ Neil Oui, à peu près. J'avais pensé à essayer deux espaces au lieu de trois, mais je n'avais pas réalisé que cela fonctionnerait si bien avant ce matin en réfléchissant à de nombreuses stratégies alternatives.
ETHproductions
3

GNU grep, 62 + 1 = 63 octets

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

Cela nécessite l' Poption. L'entrée doit être l'animal à synthétiser, suivi d'un espace, suivi de la liste des animaux de 3 lettres ouverts, fermés et délimités par des points d'exclamation. Exemple d'utilisation (en supposant que le programme soit enregistré sous 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!

Pour une entrée vraie, la ligne d'entrée est renvoyée. Pour une fausse entrée, il n'y a pas de sortie.

Merci à Martin d'avoir repéré un bug et de m'avertir de l'existence de \Bfor word non-borne.

feersum
la source
Grep n’a-t-il pas de limites non-mots \Bpour vous permettre de vous débarrasser de la dernière alerte? (Si ce n'est pas le cas, passer à Retina permettrait d'économiser quelques octets. En fait, je pense que cela économiserait de toute façon un octet, car il n'a pas besoin de l' Poption.)
Martin Ender
Je ne peux pas tester avec grep pour le moment, mais est-ce que cela gère les grands cas de test de falsy en quelques secondes? Dans Retina, le retour en arrière prend un certain temps.
Martin Ender
1
@ MartinBüttner Pour les deux derniers cas de fausseté, il a en fait abandonné et imprimé grep: exceeded PCRE's backtracking limit.
Feersum
1
Utiliser GNU pour résoudre ce problème semble très approprié.
Antti29
2

ES6, 122 121 119 104 octets

J'avais travaillé sur la manière de procéder en ce qui concerne la réponse d'ETHproduction, mais je ne pouvais pas penser à la façon de gérer le ,,,problème, alors naturellement, lorsque j'ai vu le commentaire de Peter Taylor, tout est devenu clair. Ensuite, ETHproductions a réussi à trouver un meilleur moyen de traiter le problème, ce qui économise utilement 15 octets.

L'entrée est le mot cible et un tableau de mots animaux.

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

Edit: Sauvegardé 1 octet 3 octets grâce à @ETHproductions.

* Sauf que j'ai utilisé & s parce que ça a l'air plus joli dans mon replace.

Neil
la source
Très agréable! Est-ce que l'une ou l'autre de ces choses fonctionnerait: 1) en utilisant (`(?!&&&)(${a.map...})`)comme chaîne, 2) en supprimant les parenthèses après cela, 3) en utilisant eval`/(?!&&&).../` ?
ETHproductions
@ETHproductions J'ai commis l'erreur de supprimer les éléments externes ()qui ne fonctionnent pas; avec le ()ça fonctionne et me sauve un octet. evala également besoin du ()s pour ne pas sauver plus loin, désolé.
Neil
Je pense que vous avez également une paire de parenthèses supplémentaire a.replace(...).
ETHproductions
Vous pouvez économiser un tas: s=s.replace(RegExp(a.map(a=>a.replace(/./g,"[&$&]")).join`|`),'&&')Remplacer par deux caractères au lieu de trois élimine la possibilité de rester coincé en remplaçant les trois mêmes caractères encore et encore.
ETHproductions
0

JS ES6, 77 octets

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

(c'est anonyme fn)

L'entrée est la même que celle de l'exemple ci-dessus de grep

nom d'utilisateur.ak
la source
Si vous prenez des entrées avec prompt()ne devriez-vous pas utiliser les sorties alert()? (Vous pouvez également en faire une fonction.)
Neil
@ Neil merci, j'ai utilisé anon. fn
nom d'utilisateur.ak