Znajdź trasę między dwoma artykułami z Wikipedii

25

Wprowadzenie

Ostatnio jeździłem na skypie z grupą przyjaciół i znudziliśmy się i nie mieliśmy nic do roboty, więc „wymyśliliśmy” „grę” (niektórzy w komentarzach zauważyli, że można grać w tę grę online i jest ona bardzo popularna, więc zdecydowanie nie wymyśliłem tego, chociaż nie widziałem go wcześniej). Powodem, dla którego umieszczam słowo „gra” w cudzysłowie, jest to, że nie jest to rzeczywista gra komputerowa, ale gra się w Wikipedii.

Gra jest naprawdę łatwa: ktoś wybiera jako cel artykuł w Wikipedii. Załóżmy Code Golf dla tego przykładu. Wszyscy gracze muszą wtedy zacząć od losowego artykułu (naciskając Losowy artykuł na pasku bocznym lub przechodząc do tego adresu URL) i muszą dotrzeć do „celu” tak szybko, jak to możliwe, używając tylko połączonych artykułów z artykułu, w którym aktualnie jesteś . Zasady obejmują:

  • Funkcja wyszukiwania jest niedozwolona (oczywiście)
  • Możesz klikać tylko linki w głównym tekście artykułu (w szczególności w całym tekście <div id="bodyContent">)
  • Jeśli twoja losowa strona lub jakakolwiek inna strona, na którą napotkasz, nie ma prawidłowych linków (martwe linki, pętle itp.) Lub nie ma żadnych linków, możesz rzucić je ponownie.

Wyzwanie

Oto, gdzie wchodzisz: niestety jestem całkiem zły w tej grze, ale jestem też brudnym oszustem. Więc chcę, żebyś zaimplementował dla mnie tego bota. Jestem również programistą, więc oczywiście mój dysk twardy jest pełen rzeczy takich jak kod, biblioteki i tym podobne, i mam tylko kilka bajtów pamięci do stracenia. Dlatego wyzwaniem jest Code Golf, wygrana z najmniej bajtami .

Szczegóły dotyczące wdrożenia:

  • Oczywiście nie musisz wdrażać inteligentnego bota, który zna połączenia między tematami i automatycznie wykrywa optymalną trasę. Brutalne zmuszanie to więcej niż wystarczające do tego wyzwania
  • W rzeczywistej grze liczy się czas. Twój program nie powinien zająć więcej niż 1 godzinę, aby znaleźć artykuł (ma to na celu uniknięcie luk, takich jak przypadkowi użytkownicy, którzy „w końcu” znajdą cel)
  • Jeśli nie można znaleźć ścieżki do celu (np. Martwe linki lub pętla), możesz wybrać, co robić z poniższej listy:
    • Wyjdź (wynik pozostaje taki sam)
    • Zdobądź kolejny losowy artykuł i spróbuj ponownie i nic nie rób na pętlach (wynik - = 10)
    • Zdobądź kolejny losowy artykuł na temat martwego łącza lub pętli (automatyczne wykrywanie pętli) (wynik - = 50)
    • (Przez „wynik” mam na myśli liczbę bajtów tutaj)
  • Kolejne 20 bajtów bonusowych zostanie odjęte, jeśli „prześledzisz” trasę, więc wydrukujesz tytuł każdej odwiedzanej strony.
  • Można użyć standardowych bibliotek sieciowych (aby uniknąć luk, takich jak „Stworzyłem własną bibliotekę sieciową, która indeksuje artykuły z Wikipedii”)
    • Jedyne, co powinien zrobić Twój program związany z siecią, to wysłać żądanie HTTP, aby pobrać stronę wikipedii
  • Jeśli twój program znajdzie stronę, powinien wyjść, ale jakoś zasygnalizować, że się skończył (wystarczy wydrukować znak „f” lub tytuł strony)
  • Należy unikać standardowych luk

Miłej zabawy w golfa!

(To jest moje pierwsze pytanie tutaj, więc proszę wskazać oczywiste luki i zastrzeżenia w komentarzach przed ich wykorzystaniem - dzięki: D)

Christoph Böhmwalder
źródło
1
Wystarczająco ciekawe na wyzwanie, ale nie wystarczający powód, aby zalać witrynę żądaniami.
manatwork
2
@manatwork Jestem pewien, że Wikipedia ma wystarczającą przepustowość, aby poradzić sobie z takimi „atakami”
Christoph Böhmwalder
1
Nie do końca luka, ale uważam, że ludzie narzekają, że jest to pytanie do wyszukiwania graficznego, które nie przynosi wielu nowych pomysłów. Myślę jednak, że dobrze, ta strona potrzebuje więcej pytań. (Chociaż zdecydowanie nie wymyśliłeś tej „gry”: P.)
Hobby Calvina
1
Mogłoby to być dobre wyzwanie Koth, biorąc pod uwagę średnią liczbę przeskoków z 50 biegów dla każdego bota. Dałby więcej zachęty do zbudowania bardziej inteligentnego bota.
rdans

Odpowiedzi:

12

Python 373 -> 303

Odczytuje miejsce docelowe Wikipedii z input()(dane wejściowe użytkownika) i powinno być w formacie /wiki/dest. Coś w stylu /wiki/Code_golflub /wiki/United_States. Używa również jednego miejsca na wcięcia i http://enwp.orgzamiast pełnego adresu URL Wikipedii, aby zapisać bajty.

  • -50, ponieważ jeśli znajdzie uszkodzony adres URL , otrzymuje nowy losowy adres URL.
  • -20, ponieważ wypisuje tytuł każdego odwiedzonego adresu URL (może zmienić tytuł -> URL, ale tytuł jest czystszy i faktycznie powiększa moje źródło).

Zawiesza się co jakiś czas i nie mogę zrozumieć, dlaczego. Być może z powodu ograniczeń cenowych w Wikipedii?

Znalazłem stronę Wikipedii Boston Red Sox w 9 minut 20 sekund, a stronę Stanów Zjednoczonych w mniej niż 10 sekund, więc znalezienie Code Golf nie powinno zająć zbyt długo ...

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
źródło
Nie znam dużo pytona, ale to ładnie wygląda
Christoph Böhmwalder
Czy jednak wykrywa pętle? Jeśli nie, to 10 punktów bonusowych zamiast 50
Christoph Böhmwalder
@HackerCow tak, nie będzie dwa razy odwiedzać tego samego adresu URL oprócz adresu /wiki/Special:RandomURL. W związku z tym po odwiedzeniu wielu adresów URL zużyje całą pamięć RAM.
Eric Lagergren,
Powiem tylko tak: from ... import*.
18ıʇǝɥʇuʎs
1
@DevanLoper oh strzelaj, źle odczytaj swój komentarz. Tak, jestem. Początkowo używałem import mechanize as mi przypisanie m.Browser()do atak gdy zgłoszę a.open()jestem w efekcie dzwoni mechanize.Browser().open()teraz jestem po prostu przywozu wszystkich mechanizei dostać się pominąć ... as mczęść.
Eric Lagergren,