查找两篇Wikipedia文章之间的路线


25

介绍

最近,我和一群朋友在一起,我们无聊而无聊,于是我们“发明”了一个“游戏”(评论中的一些人指出,该游戏可以在线玩并且非常受欢迎,因此我们明确没有发明它,尽管我以前从未见过)。我将“游戏”一词用引号引起来的原因是,它不是实际的计算机游戏,而是在Wikipedia上玩的。

玩起来真的很容易:有人选择一些Wikipedia文章作为目标。让我们假设此示例为Code Golf。然后,所有玩家都必须从随机文章开始(通过单击侧边栏中的Random Article或转到 URL),并且必须使用您当前所在文章的链接文章尽快到达“目标” 。规则包括:

  • 不允许使用搜索功能(显然)
  • 您只能点击文章正文中的链接(特别是内的所有文本<div id="bodyContent">
  • 如果您遇到的随机页面或任何其他页面没有有效链接(死链接,循环等),或者根本没有任何链接,则您可能会再次滚动。

挑战

这是您进入的地方:不幸的是,我在这场比赛中表现不佳,但我也是个肮脏的骗子。所以我希望你为我实现这个机器人。我也是一名程序员,所以自然地,我的硬盘上充满了代码,库之类的东西,而我只有几字节的可用内存。因此,挑战是Code Golf,以最少的字节数获胜。

实施细节:

  • 当然,您不必实现一个智能机器人,该机器人可以了解主题之间的联系并自动检测最佳路线。对于这一挑战而言,强行强行绰绰有余
  • 在实际游戏中,时间很重要。您的程序不应花超过1个小时的时间即可找到文章(这是为了避免出现诸如“最终”找到目标的随机搜索者之类的漏洞)
  • 如果找不到目标的路径(例如无效链接或循环),则可以从以下列表中选择要执行的操作:
    • 退出(分数保持不变)
    • 获取另一篇随机文章,然后重试,对循环无效(得分-= 10)
    • 在无效链接或循环上获得另一篇随机文章(自动检测循环)(得分-= 50)
    • (按“分数”表示您的字节数)
  • 如果您“跟踪”路线,则会减去另外20个奖励字节,因此您将打印访问的每个页面的标题。
  • 可以使用标准的网络库(以避免出现“我制作了自己的网络库,可检索维基百科文章”之类的漏洞)
    • 与程序相关的与网络相关的唯一事情是发送HTTP请求以下载维基百科页面
  • 如果您的程序找到该页面,则应退出,但以某种方式表明已结束(打印字符“ f”或页面标题已足够)
  • 避免标准漏洞

打高尔夫球吧!

(这是我在这里的第一个问题,因此在利用这些注释之前,请在注释中指出明显的漏洞和注意事项-谢谢:D)


1
有趣的事情足以应付挑战,但我没有足够的理由向网站发送大量请求。
manatwork 2014年

2
@manatwork我相当确定Wikipedia具有足够的带宽来处理这样的“攻击”
ChristophBöhmwalder2014年

1
并非完全是一个漏洞,但我会引起人们的抱怨,即这只是一个图搜索问题,并未带来很多新想法。但是,我认为很好,该站点需要更多问题。(尽管您绝对没有发明这个“游戏”:P。)
卡尔文的爱好2014年


1
作为Koth挑战,使用每个漫游器平均跳出50次运行的平均跳数可能会很好。将给予更多的动力来构建更智能的机器人。
rdans 2014年

Answers:


12

Python 373-> 303

它从input()(用户输入)读取Wikipedia目的地,并且格式应为/wiki/dest。因此,类似/wiki/Code_golf或的东西/wiki/United_States。它还为缩进使用一个空格,而http://enwp.org不是Wikipedia的完整URL来保存字节。

  • -50,因为如果找到一个损坏的URL它将获得一个新的随机URL。
  • -20,因为它会打印访问的每个URL的标题(可以更改title-> URL,但标题更干净,实际上使我的来源更大)。

它每隔一段时间挂一次,我不知道为什么。也许是因为维基百科的速率限制?

我在9分20秒找到了Boston Red Sox Wikipedia页面,而在10秒以内找到了美国页面,因此找到Code Golf 不需要花长时间...

from mechanize import*;from lxml.html import*;from random import*;a=Browser();a.set_handle_robots(0);i='http://enwp.org/Special:Random';t=input();d={};k=a.open
def f(o):
 if o!=i:d[o]=o
 if o in d:f(i)
 try:v=fromstring(k(o).read()).xpath('//div[@id="content"]//a/@href')
 except:f(i)
 print a.title()
 if t in v:k(t);print 'f';exit()
 else:f(choice(v)) if v else f(i)
f(i)

我不太了解python,但这看起来不错
ChristophBöhmwalder2014年

它是否检测到循环?如果不是,那将是10分而不是50分的奖励积分
ChristophBöhmwalder2014年

@HackerCow是的,除了URL之外,它不会两次访问相同的/wiki/Special:RandomURL。因此,在访问许多URL之后,它将耗尽整个RAM。
埃里克·拉格格伦

我就这样说:from ... import*
ɐɔıʇǝɥʇuʎs

1
@DevanLoper哦,开枪,误读了您的评论。我是。最初我使用的import mechanize as m是分配给它m.Browser()a所以当我打电话时a.open()实际上是在打电话,mechanize.Browser().open()现在我只是导入所有内容mechanize并跳过该... as m部分。
埃里克·拉格伦2014年
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.