动物园冒名顶替者


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)参数输出结果。

您的代码应在几秒钟内处理任何测试用例。

适用标准规则。

更多例子

  • 一个或两个字母的单词显然是虚假的。
  • 上面列表中没有的任何三个字母的单词也是如此。
  • 即使我们有gnuand rat,也gnat很虚假,因为没有办法将它们排列成只看到两个字母(我们不想将动物切成三等份)。

一些真实的例子:

pigment

    ant
  bee
 olm
pig
antioxidant

   fox
 koi  ide
ant     ant

测试用例

大多数测试用例均来自针对字典运行参考实现。最后几个“单词”是随机生成的,仅用于确保提交足够有效。

真相:

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

我仍在为更好的头衔提出建议...
Martin Ender

You may optionally receive this list as input-这是否意味着它不计入分数,而采用硬编码会计入分数?
marinus

@marinus是的。因此,您可能希望将其用作附加输入,除非在您选择的语言上读取多个字符串确实很麻烦。(我不想允许使用硬编码+“如果您愿意,请从分数中减去它”,因为这样您将使人们进行硬编码和压缩,这实际上会给他们分数带来额外的好处。)
Martin Ender

功能(输出)参数 ”是否包括引用参数
mınxomaτ

5
我不敢相信我错过了沙箱中的“整数”注释。先生,真可惜!在这两个部分的周围是一个整数,而不是30。(而且也不完全尝试遗漏雄性动物的名字-参见猪)。
彼得·泰勒

Answers:


7

Japt,51 48 45 36 33 19字节

@PeterTaylor节省了9个字节

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

在线测试!

将输入作为要测试的字符串,然后是三个字母的单词列表,以分隔|。注意:这在最新版本的解释器中不起作用,因此请使用链接,而不是复制粘贴代码。

这个怎么运作

基本思想是采用输入字符串,并用两个填充字符重复替换其中的30个单词。我使用空格作为填充字符。另外,我们要替换antin elephanta  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 2016年

1
@PeterTaylor我发现了一个更短的方法:只需用两个空格代替三个即可。最多19个字节!
ETHproductions 2016年

另一个facepalm时刻呢?
尼尔

@Neil Yep,差不多。我曾考虑过尝试使用两个空间而不是三个空间,但是直到今天早上考虑许多替代策略时,我才意识到它会如此有效。
ETHproductions 2016年

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!

对于真实输入,将回显输入线。对于错误的输入,没有输出。

感谢Martin发现了一个错误,并提醒我注意\B非边界词for 的存在。


grep是否没有非单词边界,\B所以您可以摆脱最后的前瞻性吗?(如果没有,切换到Retina会节省一些字节。实际上,我认为它还是会节省一个字节,因为它不需要此P选项。)
Martin Ender

我现在无法使用grep进行测试,但这实际上可以在几秒钟内处理庞大的测试用例吗?在视网膜中,回溯需要相当长的时间。
Martin Ender

1
@MartinBüttner对于最后几个虚假的案例,它实际上已放弃并打印了grep: exceeded PCRE's backtracking limit
feersum

1
使用GNU来解决这个问题似乎非常合适。
Antti29年

2

ES6,122个 121 119 104字节

就ETHproduction的答案而言,我已经找到了解决方法,但是却没想到如何,,,解决*问题,所以当我看到Peter Taylor的评论时,一切自然变得清晰了。然后,ETHproductions设法找到一种更好的方法来处理该问题,从而节省了15个字节。

输入是目标词和动物词数组。

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

编辑:由于@ETHproductions,节省了1个字节 3个字节。

*除我使用&s外,因为它在我的计算机中看起来更好replace


非常好!这些方法中的任何一种都可以工作:1)使用(`(?!&&&)(${a.map...})`)作为字符串,2)在这样做之后删除括号,3)使用eval`/(?!&&&).../`
ETHproductions 2016年

@ETHproductions我错误地删除了()不起作用的外部;与()它的工作原理,并节省了我一个字节。eval还需要()s,所以它不再保存任何内容,对不起。
尼尔

我认为您周围还有一对括号a.replace(...)
ETHproductions 2016年

您可以节省很多:s=s.replace(RegExp(a.map(a=>a.replace(/./g,"[&$&]")).join`|`),'&&')用两个字符代替三个字符可以消除一遍又一遍地替换相同的三个字符的麻烦。
ETHproductions 2016年

0

JS ES6,77个字节

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

(这是匿名fn)

输入与上述grep示例输入相同


如果要输入,prompt()则不应该使用来输出alert()?(或者只是使此功能起作用。)
Neil 2016年

@尼尔,谢谢,我用了匿名。fn
username.ak
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.