Vikipedi: Felsefe!


26

Bir çok ineğin wikipedia'daki sayfaların çoğunun (sanırım% 95) bildiği gibi sonunda felsefe yol açmaktadır:

Italik olmayan veya parantez içindeki ilk normal yazıya verilen parantez bağlantısına tıklayın: (yani Dosya: veya Özel değil, fakat Vikipedi: uygun).

Betik:

  • Giriş olarak ilk sayfayı al
  • Her makalenin adını yazdır
  • Ve Felsefe'ye ulaşmak için kaç tane makale yazdığını ve söylemediği takdirde yazdırın.

1000 puanla başlarsınız ve koddaki her karakter için bir tane kaybedersiniz, Bonus puanları:

Döngü yazılarını tespit etme ve durdurma: +50

Döngü yazılarını algılama ve kullanıcının makale üzerindeki bir sonraki bağlantıya geçip geçmemesi gerektiğini sorma: +170

Eski kontrolde bir komut satırı argümanı veya benzeri olarak varsayılanı kabul etmek: +140

En yüksek puan kazanır.


7
+1, büyük zorluk! Bu ayraç tespiti zor: P
Doorknob

1
Bunun daha iyi bir tanım kullanabileceği hissine kapılıyorum, ancak henüz tam olarak ne kadar tam emin değilim.
Iszi

3
Yazılan her karakter için bir puan kaybedersiniz. Hmm. Harika, anladım, sadece karakterleri kopyalayıp yapıştıracağım! Kayıp puan yok!
Justin

5
Lütfen cevaplar zaten yayınlandıktan sonra kuralları değiştirmeyin; Bu oldukça kabaca ve genellikle buradaki toplulukta kaşlarını çattı ...
Doorknob

Yanıtlar:


8

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

Yapılması gereken pek çok gelişme olduğuna eminim .

(Bu Nokogiri gerektirir)

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

Örnek çalışma:

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

Farklı bir bağlantıya gitmek zorunda kaldığım bir örnek

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

Kullandığım püf noktaları:

  • Seçiciyi p ayalnızca italik olmayan bağlantılar elde etmek için kullandım , çünkü italik olmayan asıl makaledeki tüm bağlantılar Wikipedia'da her zaman paragraf öğelerindedir.

hmmm ... belki dil ile gelen
kütüphanelerden

@ user1825860 Bu aslında dille gelen bir kütüphane değil; bu bir mücevher. Cevabımı düzenledim. Ama gerçekten, bu zorlu meseleyi atmak ve HTML ayrıştırma kütüphanelerini kullanmamıza bizi zorlamak istiyorsun? : P
Doorknob


İlk
gönderiyi

2
@ user1825860 Lütfen cevaplar zaten yayınlandıktan sonra kuralları değiştirmeyin; Bu oldukça kaba ...
Doorknob

5

"BASH " - (Hatalı değilse: 1000 - 397 + 170 + 140 = 913 puan)
"BASH" - (Hatalı değilse: 1000 - 386 + 170 + 140 = 924 puan)

"BASH" - (Yanlış değilse: 1000 - 381 + 170 + 140 = 929 puan)

BASH, * nix mermilerinde kullanılan ancak bir bash betiğine sarılmış bir araç karışımı olduğu için bilerek alıntı yapar.

Düzenleme 1:

  • Buna varsayılan http://olarak kaldırıldı curl.
  • Değiştirilen href=için çapa üzerinde maç f=olarak <a>başka yok , normal nitelikleri biten f. (Özel etiketler olasılığıdır. Şimdiye kadar hiç görmedim.)
  • Bulunmamıştır Set çıkış mesajı !Philyerine NoPhil. Bu seferki Bir de mesela diyebiliriz olarak biraz tuhaf !, 0, N, !Pveya benzeri.
  • Tuhaf iki: -saçık curl, üç bayt daha azaltmak için kaldırılabilir, ancak bu karışık bir çıktı verir. Bunun bir sorun olup olmadığından emin değilim.
  • Bu sayfadaki yardım güncellendi .

Tuhaflıklar kullanılarak kod 379 bayt, 931 puanla bitecektir.

Ayrıca @ baynapus eşleştirme (umarım) gezinti kutusunu(p|ul).*?<(\1) altı bayt ekleyerek de uygulayabilirim (altı puan çıkararak).

Düzenleme 2:

Sayaç ${#c[@]}yerine ayırma dereceleri yazdırmak için kullanılması$i

Tuhaflıklar kullanılarak kod 374 bayt, 936 punto ile sonuçlanır.


Cthulhu'yu çağırarak regexp + bash / shell / * nix çözümüne gidiyorum.

Çalıntı:

Uygulanan:

  • Döngüyü tespit edin ve bir sonraki bağlantının alınıp alınmayacağını sorun.
  • İsteğe bağlı olarak, bir sonraki bağlantıyı seçenek olarak kopyalayın.

Gereksinimler:

  • bash v.?
  • grepile -P(PCRE'nin) destekler.
  • sed
  • curl
  • cut

Kullanımı:

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.

Satır içi kodu Dosyaya kopyala. chmod +x filename. ./script /wiki/…Bash kabuğundan çalıştırın .

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[@]};

Genişletilmiş ve açık kod:

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[@]}

Kahretsin, beni bir noktaya kadar yendin! : P Çözümümü daha fazla golf
oynamak zorunda kalacağım

Ye;), ancak bunun geçerli kod olduğundan emin değil. Araçları bu şekilde kullanmak.
Runium

5

JavaScript 726 (444 karakter [556] + 170)

Şimdi bunun bir yer imi olarak geçerli olmayabileceğini takdir ediyorum, ancak yine de bunu düzeltmekten zevk aldım.

Kullanım: Başlamak istediğiniz sayfaya gidin ve aşağıdakileri konsolda çalıştırın:

(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)

JavaScript için çıktı aşağıdaki gibidir:

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

Bu çözüm, algılanan bir döngüdeki bir sonraki bağlantıya atlamak istediğinizi varsayacaktır, ancak truesonunda değiştirirseniz, falsebunun için uygun olup olmadığından emin olamadığınız bir onay kutusu açılır (oldukça sinir bozucu ...). ikincil bonus veya değil. Kabul etmeyeceğim.

Girintili'ye:

(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

Bu yüzden aslen parenlerdeki maddeleri görmezden gelme kısmını özledim, bunun daha da endişe verici olduğunu ekledim, bu yüzden bu filtre işlevini yerine getirmeyi umuyorum (veya umarım tamamen değiştiririm).

Hem Chrome hem de Firefox'ta çalışma (Firefox 26'da test edilmiştir)


2
Müthiş görünüyor, ancak Firefox 20'de başarısız oluyor.
Ocak'ta

Argghh! Sadece Chrome'u test ettim. Ben içine bakacağım!
Dom Hastings

@boothby Şimdi Firefox'ta çalışıyor olmalı ... Yine de seçtiğim bağlantılar üzerinde çalışmak istiyorum!
Dom Hastings

5

813 karakter

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

Harici kütüphaneler yok. Döngü algılama .

Birinci argüman Kaynak Makale, ikincisi Hedef Makaledir.

Golf versiyonu:

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);
    }
}

Akıllı sürüm:

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);
    }
}

Örnek çalışma, "Gökyüzü" den "Felsefe" ye:

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:\>

5

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

Zaten tüketilmişse, bir sonraki bağlantıyı otomatik olarak alan güncellenmiş çözüm. 140 bonus puan için teşekkürler.

Mantık: İçinde ":" bulunmayan ilk "/ wiki" linkini al ("Dosya:" linklerini yoksayar). Her seferinde sayımı + 1 döndürerek yinelemeyle durulayın ve tekrarlayın. Önceki tüm çıktıların bir listesini elimde tutarım, böylece program sonsuz bir döngüye girmiyor.

Düzenli İfade: Düzenli ifadenin 2 biçimine sahibim.

  • "<p>.*?\"/wiki/([^:]*?)\".*?/p>"hangi <p>etiketlerin içindeki bağlantıları bulur
  • "p>.*?/wiki/([^:]*?)\""bu, çalışmasının kanıtlandığı ancak farklı sonuçlar verdiği, biraz daha deneysel bir etikettir, çünkü zaman zaman sağ taraftaki bilgi çubuğundan bağlantılar alır. Bunlar normal makaleler, bu yüzden hala geçerli olduğuna inanıyorum. Olmama konusunda kararsız kalırsa, OP (veya başkası) yorum bırakabilir ve çözümümü daha iyi bir eski durumuna güncelleyebilirim.

İşe yaramadığı ya da OP'nin kenar çubuğundan bağlantı almaya izin verilmediğini söyleyen bir test vakası bulana kadar ikinci normal ifadeyi kullanacağım (bence, bilgi çubukları hala asıl makalenin kendisi; bir özeti).


Küçültülmüş Kaynak:

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}}}

Okunabilir kaynak:

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
    }
  }
}

Örnek çıktı:

Giriş

Space_toilet

Çıktı

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

1
Scala ana nesne veya yöntem gerektirmez. Tercüman ile "scala <filename> [args ..]" olarak çalıştırabilirsiniz. args(0)İlk argümanı almak için kullanın , sizden objectve maintanımlardan kurtulun ve siz de bunları kaldırabilirsiniz :Int. pastebin.com/YqywKcG8
KChaloux

Çıkaramıyorsunuz : Int. Özyinelemeli bir çağrı yaptığını anlamadın. Ayrıca pastörüm eski Okunabilen Kaynağınızdan alındı, ancak aynı kavramlar geçerli.
KChaloux

Ana yöntemden kurtulmayı deneyeceğim. Ve evet, özyinelemeli aramalar :Intorada ekledim. Bugün daha sonra, sahip olduğum 333 char çözümünün okunabilir bir formunu ekleyeceğim. Önerileriniz için teşekkürler @KChaloux
javatarz

1
Dediğim gibi, object Q extends App { ... }kodu scalac ile derlemek yerine tercümanla çalıştırıyorsanız , başvuru tamamen gereksizdir. Sadece koşscala <filename> [args..]
KChaloux

4

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

Döngü algılandığında kullanıcılara nasıl ilerlemelerini isteyen sürüm

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)

Girinti ve yorumlarla:

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)

Örnek çalışma:

> 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; ??? makas

Varsayılan olarak, gereksiz olmayan ilk bağlantıyı alır (örn. Döngü oluşturmaz).

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.