Trouver un itinéraire entre deux articles Wikipedia

25

introduction

Récemment, je skypais avec un groupe d'amis et nous nous ennuyions et n'avions rien à faire, alors nous avons "inventé" un "jeu" (certaines personnes dans les commentaires ont souligné que ce jeu est jouable en ligne et très populaire, donc nous avons définitivement Je ne l'ai pas inventé, même si je ne l'avais jamais vu auparavant). La raison pour laquelle j'ai mis le mot "jeu" entre guillemets est parce que ce n'est pas un jeu informatique réel, mais qu'il est joué sur Wikipedia.

C'est vraiment facile à jouer: quelqu'un choisit un article Wikipedia comme objectif. Supposons Code Golf pour cet exemple. Tous les joueurs doivent ensuite partir d'un article aléatoire (en appuyant sur Article aléatoire dans la barre latérale ou accéder à cette URL) et atteindre le "but" aussi rapidement que possible en utilisant uniquement les articles liés de l'article où vous vous trouvez actuellement . Les règles comprennent:

  • La fonction de recherche n'est pas autorisée (évidemment)
  • Vous ne pouvez cliquer que sur des liens dans le texte principal de l'article (en particulier tout le texte à l'intérieur <div id="bodyContent">)
  • Si votre page aléatoire ou toute autre page que vous rencontrez n'a pas de liens valides (liens morts, boucles, etc.) ou aucun lien du tout, vous pouvez recommencer.

Le défi

Voici où vous intervenez: malheureusement, je suis assez mauvais dans ce jeu, mais je suis aussi un tricheur sale. Je veux donc que vous implémentiez ce bot pour moi. Je suis aussi programmeur, donc naturellement mon disque dur est plein de trucs comme du code, des bibliothèques et autres et je n'ai que quelques octets de mémoire à revendre. Par conséquent, ce défi est Code Golf, la réponse avec le moins d' octets gagne.

Détails d'implémentation:

  • Bien sûr, vous n'avez pas à implémenter un bot intelligent qui connaît les connexions entre les sujets et détecte automatiquement l'itinéraire optimal. Le forçage brutal est plus que suffisant pour ce défi
  • Dans le jeu, le temps compte. Votre programme ne devrait pas prendre plus d'une heure pour trouver l'article (c'est pour éviter les failles comme les chercheurs aléatoires qui trouveront "éventuellement" l'objectif)
  • Si aucun chemin vers l'objectif ne peut être trouvé (par exemple des liens morts ou une boucle), vous pouvez choisir quoi faire dans la liste ci-dessous:
    • Quitter (le score reste le même)
    • Obtenez un autre article au hasard et réessayez et ne faites rien sur les boucles (score - = 10)
    • Obtenez un autre article aléatoire sur un lien mort ou une boucle (détection automatique des boucles) (score - = 50)
    • (Par "score", je veux dire votre nombre d'octets ici)
  • 20 autres octets supplémentaires seront soustraits si vous "tracez" l'itinéraire, vous imprimez donc le titre de chaque page individuelle que vous visitez.
  • Des bibliothèques réseau standard peuvent être utilisées (pour éviter les failles comme "J'ai créé ma propre bibliothèque réseau qui explore les articles wikipedia")
    • La seule chose liée à votre réseau que votre programme devrait faire est d'envoyer une requête HTTP pour télécharger une page wikipedia
  • Si votre programme trouve la page, il devrait se fermer, mais signale d'une manière ou d'une autre qu'elle est terminée (l'impression du caractère "f" ou du titre de la page suffit)
  • Les failles standard doivent être évitées

Amusez-vous au golf!

(Ceci est ma première question ici, alors veuillez signaler les lacunes et les mises en garde évidentes dans les commentaires avant de les exploiter - merci: D)

Christoph Böhmwalder
la source
1
Assez intéressant pour un défi, mais pas une raison suffisante pour inonder un site de demandes.
manatwork
2
@manatwork Je suis pratiquement certain que Wikipédia a suffisamment de bande passante pour gérer des "attaques" comme celle-ci
Christoph Böhmwalder
1
Pas exactement une échappatoire, mais je chercherais des gens se plaignant que ce n'est qu'une question de recherche de graphique qui n'apporte pas beaucoup de nouvelles idées à la table. Je pense cependant que ça va, ce site a besoin de plus de questions. (Bien que vous n'ayez certainement pas inventé ce "jeu": P.)
Calvin's Hobbies
1
Cela aurait pu être un bon défi en prenant le nombre moyen de sauts sur 50 pistes avec chaque bot. Donnerait plus d'incitation à construire un bot plus intelligent.
rdans

Réponses:

12

Python 373 -> 303

Il lit la destination Wikipedia à partir de input()(entrée utilisateur) et doit être au format /wiki/dest. Donc, quelque chose comme /wiki/Code_golfou /wiki/United_States. Il utilise également un espace pour les retraits et http://enwp.orgau lieu de l'URL complète de Wikipedia pour enregistrer les octets.

  • -50 car s'il trouve une URL cassée, il obtient une nouvelle URL aléatoire.
  • -20 car il imprime le titre de chaque URL visitée (pourrait changer le titre -> URL, mais le titre est plus propre et agrandit ma source).

Il se bloque de temps en temps, et je ne peux pas comprendre pourquoi. Peut-être à cause des limites de taux de Wikipédia?

J'ai trouvé la page Wikipedia des Boston Red Sox en 9 minutes 20 secondes et la page États-Unis en moins de 10 secondes, donc ça ne devrait pas prendre trop de temps pour trouver 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)
Eric Lagergren
la source
Je ne connais pas beaucoup de python, mais cela a l'air sympa
Christoph Böhmwalder
Détecte-t-il les boucles? Si ce n'est pas le cas, c'est 10 points bonus au lieu de 50
Christoph Böhmwalder
@HackerCow oui, il ne visitera pas la même URL deux fois, sauf pour l' /wiki/Special:Randomurl. Par conséquent, après avoir visité de nombreuses URL, votre mémoire RAM entière sera consommée.
Eric Lagergren
Je vais vous dire ceci: from ... import*.
ɐɔıʇǝɥʇuʎs
1
@DevanLoper oh shoot, a mal lu votre commentaire. Oui. À l'origine, j'utilisais import mechanize as met l'attribution m.Browser()à adonc quand j'appelle, a.open()j'appelle en fait mechanize.Browser().open()maintenant, je suis juste en train d'importer tout mechanizeet de sauter la ... as mpartie.
Eric Lagergren