Wikipedia: Filsafat!

26

Karena banyak Geeks mungkin tahu sebagian besar halaman (95% saya pikir) di wikipedia akhirnya mengarah ke Filsafat seperti ini:

Klik tautan non-italic pertama atau di dalam tanda kurung yang menuju ke artikel normal lainnya: (yaitu bukan File: atau Special :, tetapi hal-hal seperti Wikipedia: boleh) dan ulangi yang itu sampai Anda mencapai filosofi.

Skrip harus:

  • Ambil halaman pertama sebagai masukan
  • Cetak nama setiap artikel
  • Dan cetak berapa banyak artikel yang diperlukan untuk sampai ke Filsafat, dan jika tidak dikatakan demikian.

Anda mulai dengan 1000 poin, dan kehilangan satu untuk setiap karakter dalam kode, poin Bonus untuk:

Mendeteksi pengulangan artikel dan berhenti: +50

Mendeteksi pengulangan artikel dan meminta apakah pengguna harus membuka tautan berikutnya pada artikel: +170

Mengizinkan default pada pemeriksaan sebelumnya sebagai arg baris perintah atau serupa: +140

Kemenangan skor tertinggi.

AlphaModder
sumber
7
+1, tantangan besar! Deteksi tanda kurung ini sulit: P
Doorknob
1
Saya merasa ini bisa menggunakan definisi yang lebih baik, tapi saya belum tahu pasti bagaimana melakukannya.
Iszi
3
Kalah satu poin untuk setiap karakter yang diketik. Hmm. Hebat, saya mengerti, saya hanya akan menyalin-tempel karakter! Tidak ada poin yang hilang!
Justin
5
Tolong jangan mengubah aturan setelah jawaban sudah diposting; itu cukup kasar dan umumnya disukai di komunitas di sini ...
Gagang Pintu

Jawaban:

8

Ruby, 1000 - 303 299 337 - 50 373 - 170 382 - 170 - 140 379 - 170 - 140 karakter = 697 701 713 797 928 931

Saya yakin ada banyak perbaikan yang harus dilakukan.

(Ini membutuhkan Nokogiri)

require'open-uri'
require'nokogiri'
x="/wiki/"+gets.chomp
r=[n=i=0]
until x=~/\/Philosophy/
d=Nokogiri.HTML open"http://en.wikipedia.org#{x}"
x=d.css('p a').select{|a|t=a.xpath('preceding::text()').map(&:text)*'';t.count('(')==t.count(')')&&a.attr('href')=~/^.wiki[^:]+$/}[i].attr'href'
i=0
puts r.index(x)?"#{$><<'i=';i=($*[0]||gets).to_i;''}": r.push(x)[-1][6..-1]
n+=1
end
p n

Contoh dijalankan:

c:\a\ruby>wikipedia_crawl_philosophy
Latin (note: this is my input)
Classical_antiquity
History
Umbrella_term
Terminology
Word
Linguistics
Science
Knowledge
Fact
Proof_(truth)
Argument
Logic
Reasoning
Consciousness
Quality_(philosophy)
Property_(philosophy)
Modern_philosophy
Philosophy
18

Contoh satu tempat saya harus pergi ke tautan yang berbeda

c:\a\ruby>wikipedia_crawl_philosophy
Snow
Precipitation_(meteorology)
Meteorology
Atmospheric_physics
Synoptic_scale_meteorology
i=2 // I put the 0-indexed number of the link I wanted to go to (so, the third link)

Weather
Atmosphere
Gas
State_of_matter#The_four_fundamental_states
Physics
Natural_science
Sciences
Knowledge
Fact
Proof_(truth)
Argument
Logic
Reasoning
Consciousness
Quality_(philosophy)
Property_(philosophy)
Modern_philosophy
Philosophy
25

Trik yang saya gunakan:

  • Saya menggunakan pemilih p auntuk hanya mendapatkan tautan non-italic, karena semua tautan dalam artikel aktual yang bukan huruf miring selalu dalam elemen paragraf di Wikipedia.
Gagang pintu
sumber
hmmm ... mungkin saya harus melarang perpustakaan kecuali yang datang dengan bahasa ...
AlphaModder
@ user1825860 Ini sebenarnya bukan perpustakaan yang datang dengan bahasa; itu adalah permata. Saya mengedit jawaban saya. Tapi sungguh, Anda ingin mengambil tantangan yang sudah sulit ini dan memaksa kami untuk tidak menggunakan parsing pustaka HTML juga? : P
Doorknob
saya tidak melarangnya tetapi Anda kehilangan poin: P
AlphaModder
Anda harus membaca ulang posting pertama dan mengedit sesuai: P
AlphaModder
2
@ user1825860 Tolong jangan mengubah aturan setelah jawaban sudah diposting; itu cukup kasar ...
Gagang Pintu
5

"BASH " - (Jika tidak salah: 1000 - 397 + 170 + 140 = 913 poin)
"BASH" - (Jika tidak salah: 1000 - 386 + 170 + 140 = 924 poin)

"BASH" - (Jika tidak salah: 1000 - 381 + 170 + 140 = 929 poin)

BASH sengaja mengutip karena ini adalah campuran alat yang digunakan dalam shell * nix tetapi dibungkus dengan skrip bash.

Edit 1:

  • Dihapus http://sebagai curldefault untuk ini.
  • Berubah href=pertandingan pada jangkar untuk f=sebagai <a>tidak memiliki lain yang normal atribut berakhir di f. (Ini kemungkinan tag khusus. Sejauh ini belum melihat.)
  • Setel pesan keluar di bukan ditemukan !Philbukan NoPhil. Yang satu ini aneh bit sebagai Satu juga bisa mengatakan misalnya !, 0, N, !Patau serupa.
  • Cara kedua: -saktif curldapat dihapus untuk mengurangi tiga byte lagi, tetapi itu akan menghasilkan output yang berantakan. Tidak yakin apakah itu masalah.
  • Bantuan yang diperbarui di halaman ini.

Menggunakan quirks, kode akan berakhir pada 379 byte, 931 poin.

Saya juga bisa menerapkan @plannapus penggunaan kotak navigasi yang cocok (semoga) dengan (p|ul).*?<(\1)menambahkan enam byte (mengurangi enam poin).

Edit 2:

Menggunakan ${#c[@]}untuk mencetak derajat pemisahan, bukan $icounter.

Menggunakan quirks, kode akan berakhir pada 374 byte, 936 poin.


Saya memanggil Cthulhu dan mencari solusi regexp + bash / shell / * nix.

Dicuri:

Diimplementasikan:

  • Deteksi loop dan tanyakan apakah tautan selanjutnya harus diambil.
  • Secara opsional pilih tautan selanjutnya pada duplikat sebagai opsi.

Persyaratan:

  • bash v.?
  • grepdengan -Pdukungan (PCRE).
  • sed
  • curl
  • cut

Pemakaian:

script PATH [OPTIONS]

Print separation of article from ``PATH'' to ``Philosophy'' on Wikipedia.
Degrees of separation, if found, is printed as last line. 
If not found last line yields ``!Phil''.

PATH    
     Absolute path to starting article, e.g: /wiki/Word 
OPTIONS
     y   Automatically select next link if already visited.
     n   (Or other) Quit if next link already visited.
BUGS
     1. On previous visit; "next link" is not checked. Thus if next link
     has already been visited we get eternal loop. Not sure if this
     disqualify +170 points.
     2. Sure there are.

Kode sebaris. Salin ke file. chmod +x filename. Dijalankan ./script /wiki/…dari bash shell.

u=($1);c=($1);while ! [[ "$u" =~ /Philosophy$ ]];do echo "$u";u=($(curl -s "en.wikipedia.org$u"|tr '\n' ' '|grep -Po '<p>.*?</p>'|sed 's/>[^<]*([^)]*)//g'|grep -o '<a [^>]*f="/wiki/[^":]*"'|cut -d\" -f2));for x in "${c[@]}";do if [ "$x" = "$u" ];then [ $2 ] &&s=$2||read -p "${u[0]}?" s;[ $s = y ] &&u[0]=${u[1]}||{ echo "!Phil";exit;} fi;done;c=("${c[@]}" "$u");done;echo ${#c[@]};

Kode diperluas dan dijelaskan:

u=($1); # Array of paths.
c=($1); # Array of visited paths.
# While $u != /Philosophy, ugly trick is to use $u instead of ${u[0]}.
while ! [[ "$u" =~ /Philosophy$ ]];do   
        echo "$u";      # Print current page.
        # curl   : prints retreived page to stdout. "-s" could be skipped.
        # tr     : replace all newline with space. This is a ®sanity thing when it comes to 
        #          twidling with html using regex.
        # grep 1 : match <p> tags. Using -P's ungreedy *?.
        # sed    : remove all occurences of "(" something ")".
        # grep 2 : match links where "href" attribute starts with /wiki/ and is not e.g. File:
        # cut    : match actual href value.
        # Result is added to array ``u''.
        u=($(curl -s "en.wikipedia.org$u" |
                tr '\n' ' ' | 
                grep -Po '<p>.*?</p>' | 
                sed 's/>[^<]*([^)]*)//g' | 
                grep -o '<a [^>]*f="/wiki/[^":]*"' | 
                cut -d\" -f2));

        # For previously visited pages as x.
        for x in "${c[@]}"; do 
                # If x equals to first page ...
                if [ "$x" = "$u" ]; then        
                        # Use option or ask.
                        [ $2 ] && s=$2 || read -p "${u[0]}?" s; 
                        # If response is "y" use next link, else exit with status.
                        [ $s = y ] && u[0]=${u[1]} || { 
                                echo "!Phil"; 
                                exit;
                        } 
                fi;
        done;
        # Append current link to "visited"
        c=("${c[@]}" "$u"); 
done;
# Print number of visited pages.
echo ${#c[@]}
Runium
sumber
Sialan, Anda mengalahkan saya dengan satu poin! : P Saya akan harus golf solusi saya lebih
Doorknob
Kamu;), tetapi tidak yakin ini adalah kode yang valid. Menggunakan alat dengan cara ini.
Runium
5

JavaScript 726 (444 karakter [556] + 170)

Sekarang saya menghargai bahwa ini mungkin tidak valid sebagai bookmarklet, tetapi saya tetap menikmati bermain-main dengannya.

Penggunaan: Navigasikan ke halaman yang ingin Anda mulai dan jalankan yang berikut di konsol:

(function(a){c=0,o="";$(u="html")[u](f=$('<iframe src="'+location+'?">').on("load",function(){$=f.contentWindow.$;p=f.contentDocument.title[s="split"](" - ")[0];c++;p=="Philosophy"?document.write("<pre>"+o+p+"\n"+c):(i=RegExp("^"+p+"$","m").test(o)?a||confirm("Loop, try next?")?2:0:1)&&(f.src=$("p>a").filter(function(){return(t=$(this).parent()[u]()[s](this.outerHTML)[0])[s]("(").length==t[s](")").length})[--i].href);o+=p+"\n"})[0])})(true)

Untuk JavaScript hasilnya adalah sebagai berikut:

JavaScript
Interpreter (computing)
Computer science
Science
Knowledge
Fact
Proof (truth)
Argument
Logic
Reason
Consciousness
Quality (philosophy)
Property (philosophy)
Modern philosophy
Philosophy
15

Solusi ini akan menganggap Anda ingin melompat ke tautan berikutnya pada satu loop yang terdeteksi, tetapi jika Anda mengubah truepada akhirnya falseakan muncul kotak konfirmasi (cukup menjengkelkan ...) tidak yakin apakah itu memenuhi syarat untuk bonus sekunder atau tidak. Saya akan berasumsi tidak.

Bertakuk:

(function(l){
    c=0,o='';
    $(u='html')[u](f=$('<iframe src="'+location+'?">').on('load',function(){ // Firefox needs the ? to properly load the frame
        $=f.contentWindow.$; // reference repeated calls as strings to save more bytes
        p=f.contentDocument.title[s='split'](' - ')[0]; // get the title

        c++;
        p=='Philosophy'?
            document.write('<pre>'+o+p+'\n'+c): // pre for nice formatting
            (i=RegExp('^'+p+'$','m').test(o)?
                l||confirm('Loop, try next?')?
                    2: // desired index + 1 so we can use as a boolean
                    0
                :
                1)&&
            (f.src=$('p>a').filter(function(){
                return (t=$(this).parent()[u]()[s](this.outerHTML)[0])[s]('(').length == t[s](')').length // shorter, but still not overly happy with this...
            })[--i].href);
            o+=p+'\n' // update output
    })[0])
})(true) // change this to show confirm box when loop detected

Jadi saya awalnya melewatkan bagian tentang mengabaikan item di parens, menambahkan yang membuatnya jauh lebih bertele-tele, jadi saya berharap untuk golf yang fungsi filter turun (atau mudah-mudahan ganti seluruhnya).

Bekerja di Chrome dan Firefox (diuji di Firefox 26)

Dom Hastings
sumber
2
Terlihat luar biasa, tetapi gagal di Firefox 20.
boothby
Argghh! Saya hanya menguji Chrome. Saya akan memeriksanya!
Dom Hastings
@ boothby Seharusnya bisa berfungsi di Firefox sekarang ... Masih ingin bekerja di tautan yang saya pilih!
Dom Hastings
5

C # - 813 karakter

Nilai: 1000-813 + 50 + 170 + 140 = 547 :(

Tidak ada perpustakaan eksternal. Deteksi loop .

Argumen pertama adalah Artikel Sumber, kedua adalah Artikel Target.

Versi golf:

class Program
{
    static void Main(string[] a)
    {
        Func<XmlDocument,IList<string>> G=delegate(XmlDocument xd){return xd.SelectNodes("//p//a[starts-with(@href,'/wiki/') and not(contains(@href,':'))]").Cast<XmlNode>().Select(n=>n.Attributes["href"].InnerText).ToList();};Action<string> W=delegate(string s){Console.WriteLine(s);};var h=new HashSet<string>();var c=new WebClient();var x=new XmlDocument();var t=c.DownloadString(@"http://wikipedia.org/wiki/"+a[0]);int i=0,C=0;
    GO:
        x.LoadXml(t);var ns=G(x);
    COL:
        var f=ns[i];if(f.Equals("/wiki/"+a[1],StringComparison.OrdinalIgnoreCase)){goto END;}if(h.Contains(f)){W("loop: "+f);i++;goto COL;}else{h.Add(f);i=0;C++;}W(f);t=c.DownloadString(@"http://wikipedia.org"+f);goto GO;
    END:
        W("Found in "+C);
    }
}

Versi cerdas:

class Program
{
    // arg[0] source article. arg[1] target article
    static void Main(string[] arg)
    {
        Func<XmlDocument, IList<string>> G = delegate(XmlDocument xd)
        {
            return xd.SelectNodes("//p//a[starts-with(@href,'/wiki/') and not(contains(@href,':'))]").Cast<XmlNode>().Select(n => n.Attributes["href"].InnerText).ToList();
        };
        Action<string> W = delegate(string s) { Console.WriteLine(s); };
        var h = new HashSet<string>(); var c = new WebClient(); var x = new XmlDocument();
        var allText = c.DownloadString(@"http://wikipedia.org/wiki/" + arg[0]);
        int i = 0; int C = 0;
    GO:
        x.LoadXml(allText);
        var ns = G(x);
    COL:
        var f = ns[i];
        if (f.Equals("/wiki/" + arg[1], StringComparison.OrdinalIgnoreCase))
        {
            goto END;
        }
        if (h.Contains(f))
        {
            W("loop: " + f); i++; goto COL;
        }
        else
        {
            h.Add(f); i = 0; C++;
        }
        W(f);
        allText = c.DownloadString(@"http://wikipedia.org" + f);
        goto GO;
    END:
        W("Found in " + C);
    }
}

Contoh lari, dari "Langit" ke "Filsafat":

C:\>wiki.exe Sky Philosophy

/wiki/Earth
/wiki/Geometric_albedo
/wiki/Phase_angle_(astronomy)
/wiki/Observational_astronomy
/wiki/Astronomy
/wiki/Natural_science
/wiki/Sciences
/wiki/Latin_language
/wiki/Classical_antiquity
/wiki/History
/wiki/Ancient_Greek
/wiki/Greek_language
/wiki/Modern_Greek
loop: /wiki/Greek_language
/wiki/Colloquialism
/wiki/Word
/wiki/Linguistics
/wiki/Science
loop: /wiki/Latin_language
/wiki/Knowledge
/wiki/Fact
/wiki/Latin
loop: /wiki/Classical_antiquity
/wiki/Italic_languages
/wiki/Indo-European_languages
/wiki/Language_family
/wiki/Language
/wiki/Human
/wiki/Extinct
/wiki/Biology
loop: /wiki/Natural_science
/wiki/Life
loop: /wiki/Earth
/wiki/Physical_body
/wiki/Physics
loop: /wiki/Greek_language
loop: /wiki/Natural_science
/wiki/Matter
/wiki/Rest_mass
/wiki/Center_of_momentum_frame
loop: /wiki/Physics
/wiki/Inertial_frame
loop: /wiki/Physics
/wiki/Frame_of_reference
loop: /wiki/Physics
/wiki/Coordinate_system
/wiki/Geometry
loop: /wiki/Ancient_Greek
/wiki/Mathematics
/wiki/Quantity
/wiki/Property_(philosophy)
/wiki/Modern_philosophy
Found in 41

C:\>
thepirat000
sumber
5

Scala (294 karakter => 1000-294 + 140 = 846 poin)

Solusi yang diperbarui yang secara otomatis mengambil tautan berikutnya jika sudah digunakan. Terima kasih untuk 140 poin bonus.

Logika: Ambil tautan "/ wiki" pertama yang tidak memiliki ":" di dalamnya (jadi abaikan tautan "File:"). Bilas dan ulangi dengan rekursi mengembalikan hitungan +1 setiap waktu. Saya menyimpan daftar semua keluaran sebelumnya berguna sehingga program tidak masuk ke loop tak terbatas.

Ekspresi Reguler: Saya memiliki 2 bentuk ekspresi reguler.

  • "<p>.*?\"/wiki/([^:]*?)\".*?/p>"yang menemukan tautan di dalam <p>tag
  • "p>.*?/wiki/([^:]*?)\""yang merupakan tag sedikit lebih eksperimental yang telah terbukti berfungsi tetapi memberikan hasil yang berbeda karena, terkadang, mengambil tautan dari bilah info sisi kanan. Ini adalah artikel biasa jadi saya yakin ini masih berlaku. Jika diputuskan tidak, OP (atau orang lain) dapat memberi saya komentar dan saya dapat memperbarui solusi saya ke reg-ex yang lebih baik.

Saya akan menggunakan persamaan reguler kedua hingga menemukan kasus uji yang tidak berfungsi atau OP menyebutkan pengambilan tautan dari bilah samping tidak diizinkan (menurut saya, bilah info masih menjadi bagian dari artikel yang sebenarnya itu sendiri; lebih dari ringkasan).


Sumber yang Diminimalkan:

object W extends App{print(x(Seq(args(0))));def x(s:Seq[Any]):Int={val? =s.last;println(?);?match{case "Philosophy"=>1;case _=>x(s:+"p>.*?/wiki/([^:]*?)\".*?/p>".r.findAllMatchIn(io.Source.fromURL("http://en.wikipedia.org/wiki/"+ ?).getLines.mkString).map(_ group 1).filter(!s.contains(_)).next)+1}}}

Sumber yang Dapat Dibaca:

object W extends App {
  print(x(Seq(args(0))))

  def x(s: Seq[Any]): Int = {
    val ? = s.last
    println(?)
    ? match {
      case "Philosophy" => 1
      case _ => x(s :+ "p>.*?/wiki/([^:]*?)\"".r.findAllMatchIn(io.Source.fromURL("http://en.wikipedia.org/wiki/" + ?).getLines.mkString).map(_ group 1).filter(!s.contains(_)).next) + 1
    }
  }
}

Output sampel:

Memasukkan

Space_toilet

Keluaran

Space_toilet
Weightlessness
G-force
Weight
Force
SI_unit
French_language
Second_language
Language_acquisition
Word
Linguistics
Science
Latin_language
Pontifical_Academy_for_Latin
Pope_Benedict_XVI
Pope_Benedict_(disambiguation)
Regnal_name#Catholic_Church
Monarch
State_(polity)
Community
Commutative_property
Mathematics
Quantity
Property_(philosophy)
Modern_philosophy
Philosophy
26
j_textz
sumber
1
Scala tidak memerlukan objek atau metode utama. Anda dapat menjalankannya dengan interpreter sebagai "scala <filename> [args ..]". Gunakan args(0)untuk mendapatkan argumen pertama, singkirkan definisi Anda objectdan main, dan saya pikir Anda juga bisa menghapusnya :Int. pastebin.com/YqywKcG8
KChaloux
Ternyata Anda tidak dapat menghapus : Int. Tidak menyadari Anda melakukan panggilan rekursif. Pastebin saya juga diambil dari Sumber Baca Anda yang lama, tetapi konsep yang sama berlaku.
KChaloux
Saya akan mencoba menyingkirkan metode utama. Dan ya, panggilan rekursif membuat saya menambahkan di :Intsana. Kemudian hari ini, saya juga akan menambahkan bentuk yang dapat dibaca dari solusi 333 char yang saya miliki. Terima kasih atas saran @KChaloux
jegroz
1
Seperti yang saya katakan, referensi untuk object Q extends App { ... }benar-benar tidak perlu jika Anda menjalankan kode dengan juru alih-alih kompilasi dengan scalac. Jalankan saja denganscala <filename> [args..]
KChaloux
4

R, 379 karakter; 1000-379 + 170 = 791 poin

Versi yang menanyakan pengguna bagaimana melanjutkan ketika perulangan terdeteksi

library(XML);w="http://en.wikipedia.org";W="/wiki/";n=1;A=c(scan(,""));while(A[n]!="Philosophy"){a=paste0(w,W,A[n]);d=sapply(strsplit(grep(W,sapply(xpathApply(xmlParse(readLines(a)),"//p/a[@href]|//ul/li/a[@href]",xmlAttrs),`[`,'href'),v=T),"/"),`[`,3);B=d[-grep(":",d)];n=n+1;if(B[1]%in%A)if(readline("Loop!2nd link?")=="n")break;A[n]=head(B[!B%in%A],1);cat(A[n],"\n")};cat(n-1)

Dengan lekukan dan komentar:

library(XML) #Uses package XML
w="http://en.wikipedia.org"
W="/wiki/"
n=1
A=c(scan(,"")) #Stdin + makes it a vector so we can store each iteration
while(A[n]!="Philosophy"){
    a=paste0(w,W,A[n])
    d=sapply(strsplit(grep(W,sapply( #The heart of the program
             xpathApply(xmlParse(readLines(a)),"//p/a[@href]|//ul/li/a[@href]",xmlAttrs),
             `[`,'href'),v=T),"/"),`[`,3)
    B=d[-grep(":",d)] #get rid of Templates, Files ,etc...
    n=n+1
    #Ask user if should proceed when loop encountered 
    #(any answer other than "n" is considered agreement):
    if(B[1]%in%A)if(readline("Loop!2nd link?")=="n")break
    A[n]=head(B[!B%in%A],1) #Take the first link that is not redundant
    cat(A[n],"\n")
    }
cat(n-1)

Contoh dijalankan:

> library(XML);w="http://en.wikipedia.org";W="/wiki/";n=1;A=c(scan(,""));while(A[n]!="Philosophy"){a=paste(w,W,A[n],sep="");d=sapply(strsplit(grep(W,sapply(xpathApply(xmlParse(readLines(a)),"//p/a[@href]|//ul/li/a[@href]",xmlAttrs),`[`,'href'),v=T),"/"),`[`,3);B=d[-grep(":",d)];n=n+1;if(B[1]%in%A)if(readline("Loop!2nd link?")=="n")break;A[n]=head(B[!B%in%A],1);cat(A[n],"\n")};cat(n-1)
1: Extended_ASCII
2: 
Read 1 item
Eight-bit 
Computer_architecture 
Computer_science 
Science 
Logic 
List_of_aestheticians 
Art 
Human_behavior 
Behavior 
Organism 
Biology 
Loop!2nd link?y
Mathematics 
Quantity 
Property_(philosophy) 
Modern_philosophy 
Philosophy 
16

R, 325 karakter; ??? poin

Versi itu, secara default mengambil tautan non-redundan pertama (yaitu non-looping).

library(XML);w="http://en.wikipedia.org";W="/wiki/";n=1;A=c(scan(,""));while(A[n]!="Philosophy"){a=paste0(w,W,A[n]);d=sapply(strsplit(grep(W,sapply(xpathApply(xmlParse(readLines(a)),"//p/a[@href]|//ul/li/a[@href]",xmlAttrs),`[`,'href'),v=T),"/"),`[`,3);B=d[-grep(":",d)];n=n+1;A[n]=head(B[!B%in%A],1);cat(A[n],"\n")};cat(n-1)
plannapus
sumber