ค้นหาเส้นทางระหว่างสองบทความใน Wikipedia


25

บทนำ

เมื่อไม่นานมานี้ฉันเล่นกับเพื่อนหลายคนและเราเบื่อและไม่มีอะไรทำเราจึง "ประดิษฐ์" เกม "(บางคนในคอมเม้นต์ชี้ให้เห็นว่าเกมนี้เล่นออนไลน์ได้และเป็นที่นิยมมาก ไม่ได้ประดิษฐ์มันแม้ว่าฉันไม่เคยเห็นมาก่อน) เหตุผลที่ฉันใส่คำว่า "เกม" ไว้ในเครื่องหมายคำพูดเพราะมันไม่ใช่เกมคอมพิวเตอร์จริง แต่เล่นใน Wikipedia

เล่นง่ายจริงๆ: มีคนเลือกบทความ Wikipedia เป็นเป้าหมาย สมมุติโค้ดกอล์ฟสำหรับตัวอย่างนี้ ผู้เล่นทุกคนแล้วต้องเริ่มต้นจากบทความแบบสุ่ม (โดยการกดสุ่มบทความในแถบด้านข้างหรือไปนี้ URL) และต้องได้รับการ "เป้าหมาย" เป็นอย่างรวดเร็วเป็นไปได้โดยใช้บทความเชื่อมโยงเพียงของบทความที่คุณมีในขณะนี้ที่ กฎรวมถึง:

  • ฟังก์ชั่นการค้นหาไม่ได้รับอนุญาต (ชัด)
  • คุณสามารถคลิกลิงค์ในข้อความหลักของบทความ (เฉพาะข้อความทั้งหมดภายใน<div id="bodyContent">)
  • หากหน้าแบบสุ่มของคุณหรือหน้าอื่น ๆ ที่คุณพบไม่มีลิงก์ที่ถูกต้อง (ลิงก์ที่ตายแล้ว, ลูป, ฯลฯ ) หรือไม่มีลิงก์ใด ๆ เลยที่คุณสามารถกลิ้งได้

ความท้าทาย

นี่คือที่ที่คุณเข้ามา: น่าเสียดายที่เกมนี้แย่มาก แต่ฉันก็เป็นสิบแปดมงกุฎสกปรกด้วย ดังนั้นฉันต้องการให้คุณใช้บ็อตนี้ให้ฉัน ฉันยังเป็นโปรแกรมเมอร์ด้วยดังนั้นฮาร์ดดิสก์ของฉันจึงเต็มไปด้วยสิ่งต่าง ๆ เช่นรหัสห้องสมุดและสิ่งเหล่านี้และฉันมีหน่วยความจำเพียงไม่กี่ไบต์เท่านั้น ดังนั้นความท้าทายนี้คือ Code Golf คำตอบที่มีจำนวนไบต์น้อยที่สุดชนะ

รายละเอียดการใช้งาน:

  • แน่นอนว่าคุณไม่จำเป็นต้องใช้บอทอัจฉริยะที่รู้การเชื่อมต่อระหว่างหัวข้อและตรวจจับเส้นทางที่เหมาะสมโดยอัตโนมัติ การบังคับให้เดรัจฉานนั้นเกินพอสำหรับความท้าทายนี้
  • ในเกมจริงเวลาจะนับ โปรแกรมของคุณไม่ควรใช้เวลานานกว่า 1 ชั่วโมงในการค้นหาบทความ (เพื่อหลีกเลี่ยงช่องโหว่เช่นผู้ค้นหาแบบสุ่มที่จะ "หาเป้าหมาย" ในที่สุด)
  • หากไม่พบเส้นทางไปยังเป้าหมาย (เช่นลิงก์ที่ไม่ทำงานหรือลูป) คุณสามารถเลือกสิ่งที่ต้องทำจากรายการด้านล่าง:
    • ออก (คะแนนยังคงเหมือนเดิม)
    • รับบทความสุ่มอีกฉบับแล้วลองอีกครั้งและไม่ทำอะไรเลยในลูป (คะแนน - = 10)
    • รับบทความสุ่มอีกอันเกี่ยวกับลิงก์ตายหรือลูป (ตรวจจับลูปโดยอัตโนมัติ) (คะแนน - = 50)
    • (โดย "คะแนน" ฉันหมายถึงจำนวนไบต์ของคุณที่นี่)
  • โบนัสจำนวน 20 ไบต์จะถูกลบหากคุณ "ติดตาม" เส้นทางดังนั้นคุณจึงพิมพ์ชื่อเรื่องของทุกหน้าที่คุณเข้าชม
  • อาจใช้ไลบรารีเครือข่ายมาตรฐาน (เพื่อหลีกเลี่ยงช่องโหว่เช่น "ฉันสร้างไลบรารีเครือข่ายของฉันเองซึ่งรวบรวมข้อมูลบทความวิกิพีเดีย")
    • สิ่งเดียวที่เครือข่ายของคุณควรทำคือส่งคำขอ HTTP เพื่อดาวน์โหลดหน้าวิกิพีเดีย
  • หากโปรแกรมของคุณค้นหาหน้ามันควรจะออก แต่อย่างใดส่งสัญญาณว่ามันเสร็จแล้ว (พิมพ์ตัวอักษร "f" หรือชื่อของหน้านั้นเพียงพอ)
  • หลีกเลี่ยงช่องโหว่มาตรฐาน

ขอให้สนุกกับการเล่นกอล์ฟ!

(นี่เป็นคำถามแรกของฉันที่นี่ดังนั้นโปรดชี้ให้เห็นช่องโหว่และคำเตือนที่ชัดเจนในความคิดเห็นก่อนที่จะใช้ประโยชน์จากพวกเขา - ขอบคุณ: D)


1
น่าสนใจพอสำหรับการท้าทาย แต่ไม่มีเหตุผลมากพอที่จะทำให้เว็บไซต์ร้องขอ
จัดการ

2
@ การทำงานฉันค่อนข้างแน่ใจว่า Wikipedia มี bandwith เพียงพอที่จะจัดการกับ "การโจมตี" เช่นนี้
Christoph Böhmwalder

1
ไม่ใช่ช่องโหว่ แต่ฉันจะระวังคนที่บ่นว่านี่เป็นเพียงคำถามในการค้นหากราฟที่ไม่ได้นำความคิดใหม่ ๆ มาสู่ตาราง อย่างไรก็ตามฉันคิดว่ามันดีไซต์นี้ต้องการคำถามเพิ่มเติม (แม้ว่าคุณจะไม่ได้ประดิษฐ์ "เกม" นี้อย่างแน่นอน: หน้า)
งานอดิเรกของ Calvin


1
นี่อาจเป็นเรื่องที่ดีเนื่องจากความท้าทายของ koth ที่นำจำนวนกระโดดเฉลี่ยจากการวิ่ง 50 ครั้งต่อบอทแต่ละตัว จะให้แรงจูงใจมากขึ้นในการสร้างบอทที่ชาญฉลาดขึ้น
rdans

คำตอบ:


12

Python 373 -> 303

มันอ่านปลายทางที่วิกิพีเดียจากinput()(การป้อนข้อมูลของผู้ใช้) /wiki/destและควรจะอยู่ในรูปแบบของ ดังนั้นสิ่งที่ต้องการหรือ/wiki/Code_golf /wiki/United_Statesนอกจากนี้ยังใช้พื้นที่หนึ่งช่องสำหรับเยื้องและhttp://enwp.orgแทนที่ URL แบบเต็มของ Wikipedia เพื่อบันทึกไบต์

  • -50 เพราะหากพบURL ที่ใช้งานไม่ได้จะได้รับ URL สุ่มใหม่
  • -20 เพราะจะพิมพ์ชื่อของแต่ละ URL ที่เข้าชม (สามารถเปลี่ยนชื่อ -> URL แต่ชื่อนั้นสะอาดกว่าและทำให้แหล่งของฉันใหญ่ขึ้นจริง ๆ )

มันค้างทุกครั้งและฉันไม่สามารถหาสาเหตุ อาจเป็นเพราะขีด จำกัด อัตรา Wikipedia หรือไม่

ฉันพบหน้า Wikipedia ของ Boston Red Soxใน 9 นาที 20 วินาทีและหน้า United States ภายใน 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)

ฉันไม่รู้จักงูหลามมากนัก แต่มันดูดีมาก
Christoph Böhmwalder

มันตรวจจับลูปหรือไม่? หากไม่เป็นเช่นนั้นนั่นคือ 10 คะแนนโบนัสแทน 50
Christoph Böhmwalder

@ แฮ็กเกอร์ใช่แล้วมันจะไม่ไปที่ URL เดียวกันสองครั้งยกเว้น/wiki/Special:RandomURL ดังนั้นหลังจากไปที่ URL จำนวนมากมันจะทำให้ RAM ทั้งหมดของคุณหมด
Eric Lagergren

from ... import*ฉันเพิ่งจะพูดแบบนี้:
Julıʇǝɥʇuʎs

1
@DevanLoper โอ้ยิงผิดอ่านความคิดเห็นของคุณ ใช่ฉันเป็น เดิมทีฉันใช้งานอยู่import mechanize as mและการมอบหมายm.Browser()ให้aดังนั้นเมื่อฉันโทรหาa.open()ฉันmechanize.Browser().open()ตอนนี้ฉันกำลังนำเข้าทั้งหมดmechanizeและข้าม... as mส่วนนั้นไป
Eric Lagergren
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.