Знайдіть маршрут між двома статтями Вікіпедії


25

Вступ

Нещодавно я перекинувся з купою друзів, і нам стало нудно і нічого робити, тому ми "придумали" "гру" (деякі люди в коментарях зазначали, що ця гра в Інтернеті і дуже популярна, тому ми визначаємо не вигадував цього, хоча я його раніше не бачив). Причиною я ставлю слово "гра" в лапки, тому що це не фактична комп'ютерна гра, але вона грається у Вікіпедії.

Це дуже просто грати: хтось обирає якусь статтю у Вікіпедії як мету. Припустимо для цього прикладу Code Golf . Після цього всі гравці повинні починати з випадкової статті (натискаючи Random Article на бічній панелі або переходячи до цієї URL-адреси) і повинні якомога швидше дістатися до "мети", використовуючи лише пов'язані статті статті, в якій ви зараз перебуваєте . Правила включають:

  • Функція пошуку заборонена (очевидно)
  • Ви можете натискати лише посилання в основному тексті статті (зокрема, весь текст всередині <div id="bodyContent">)
  • Якщо ваша випадкова сторінка або будь-яка інша сторінка, на яку ви зіткнулися, не має дійсних посилань (мертві посилання, петлі тощо) або взагалі немає посилань, ви можете прокрутити знову.

Змагання

Ось куди ви заходите: на жаль, я дуже поганий у цій грі, але я також брудний шахрай. Тому я хочу, щоб ви реалізували цього бота для мене. Я також програміст, тому природно мій жорсткий диск переповнений такими речами, як код, бібліотеки тощо, і мені залишається лише кілька байтів пам'яті. Тому цей виклик - Code Golf, відповідь з найменшими байтами виграє.

Деталі щодо впровадження:

  • Звичайно, вам не доведеться впроваджувати інтелектуальний бот, який знає зв'язки між темами і автоматично визначає оптимальний маршрут. Насильницької грубих дій більш ніж достатньо для цілей цього виклику
  • У реальній грі час рахується. Ваша програма не повинна займати більше однієї години, щоб знайти статтю (це уникнути лазівки, як випадкові пошуковики, які "зрештою" знайдуть мету)
  • Якщо шляху до цілі неможливо знайти (наприклад, мертві посилання чи цикл), ви можете вибрати, що робити зі списку нижче:
    • Вийти (оцінка залишається незмінною)
    • Отримайте ще одну випадкову статтю та спробуйте ще раз і нічого не робите на циклі (бал - = 10)
    • Отримайте ще одну випадкову статтю на мертвій посилання або циклі (автоматично визначайте цикли) (оцінка - = 50)
    • (Під "балом" я маю на увазі ваш рахунок байтів)
  • Ще 20 байтових бойтів буде віднято, якщо ви «простежите» маршрут, тож ви надрукуєте заголовок кожної окремої сторінки, яку відвідуєте.
  • Можливо використовувати стандартні мережеві бібліотеки (щоб уникнути лазівки, наприклад "Я створив власну мережеву бібліотеку, яка сканує статті у Вікіпедії")
    • Єдине, що має робити ваша програма, - це надіслати HTTP-запит на завантаження сторінки вікіпедії
  • Якщо ваша програма знайде сторінку, вона повинна вийти, але якось сигналізувати, що вона закінчена (достатньо роздрукувати символ "f" або заголовок сторінки)
  • Стандартні лазівки слід уникати

Весело гольфу!

(Це моє перше питання тут, тому, будь ласка, вкажіть очевидні лазівки та застереження в коментарях, перш ніж використовувати їх - дякую: D)


1
Досить цікавий для виклику, але недостатньо підстав для того, щоб залити сайт запитами.
манатура

2
@manatwork Я досить впевнений, що у Вікіпедії є достатня пропускна здатність для обробки таких "атак"
Крістоф Бьомвальдер

1
Не зовсім лазівка, але я би звернув увагу на людей, які скаржаться, що це лише питання пошуку графіків, яке не приносить багато нових ідей на стіл. Я думаю, що це добре, цей сайт потребує додаткових питань. (Хоча ви точно не вигадали цю «гру»: P.)
Захоплення Кальвіна


1
Це могло б бути хорошою проблемою як кот, що приймає середню кількість хмелів з 50 запусків з кожним ботом. Дав би більше стимулів для створення більш розумного бота.
rdans

Відповіді:


12

Пітон 373 -> 303

Він читає місце призначення Вікіпедії з input()(введення користувача) і має бути у форматі /wiki/dest. Отже, щось на кшталт /wiki/Code_golfабо /wiki/United_States. Він також використовує один пробіл для відступів і http://enwp.orgзамість повної URL-адреси Вікіпедії для збереження байтів.

  • -50, тому що якщо він знаходить зламану URL-адресу, він отримує нову випадкову URL-адресу.
  • -20, оскільки він друкує заголовок кожної відвіданої URL-адреси (може змінити назву -> URL, але заголовок чистіший і фактично збільшує моє джерело).

Він висить раз у раз, і я не можу зрозуміти, чому. Можливо, через обмеження швидкості у Вікіпедії?

Сторінку Вікіпедії « Бостон Ред Сокс» я знайшов за 9 хвилин 20 секунд, а сторінку Сполучених Штатів - за 10 секунд, тож для пошуку коду для гольфу не потрібно займати багато часу ...

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)

Я не знаю багато пітона, але це виглядає приємно
Крістоф Бьомвальдер

Чи виявляє це петлі? Якщо це не так, це 10 бонусних балів замість 50
Крістоф Бьомвальдер

@HackerCow, так, він не відвідуватиме один і той же URL два рази, крім /wiki/Special:RandomURL-адреси. Отже, після відвідування багатьох URL-адрес він з'їсть всю вашу оперативну пам'ять.
Ерік Лагергрен

Я просто скажу: from ... import*.
ɐɔıʇǝɥʇuʎs

1
@DevanLoper о стріляй, неправильно читай свій коментар. Так я. Спочатку я використовував import mechanize as mі призначення m.Browser()на aтак , коли я дзвоню a.open()я в сутності , що закликає mechanize.Browser().open()зараз я просто імпортує все mechanizeі отримати , щоб пропустити ... as mчастину.
Ерік Лагергрен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.