Napisz program, który sam się pobiera


66

Napisz program, który łączy się z tą witryną, pobiera samą odpowiedź, w której jest opublikowany, wypakowuje własny kod źródłowy i drukuje go. Dane wyjściowe muszą być identyczne z kodem źródłowym. Najkrótszy kod (w bajtach) wygrywa.

Zasady:

  • Niedozwolone są skracacze adresów URL.
  • Odpowiedź musi mieć zwykły format - nagłówek z nazwą i rozmiarem języka, opcjonalnym opisem, blokiem kodu, opcjonalnym opisem i objaśnieniem. Niedozwolone są nienaturalne ograniczniki.
  • Dane wyjściowe muszą pochodzić z rzeczywistego bloku kodu opublikowanego na stronie.
  • Funkcjonalność nie może zależeć od pozycji na liście odpowiedzi; powinien działać, nawet jeśli istnieje wiele stron, a odpowiedzi nie ma na pierwszej.
  • Nowość: specjalna uwaga na odpowiedzi, które mają być uruchamiane w przeglądarce: można wymagać ich uruchomienia w domenie codegolf (aby przestrzegać zasad tego samego pochodzenia), ale domena i ścieżka powinny zostać uwzględnione w rozwiązaniu, aby zrób to uczciwie.

39
Catch-22: Jak mam przetestować swoje zgłoszenie?
Martin Ender

9
Widzę ludzi, którzy publikują odpowiedzi i usuwają je, aby mogli przetestować swój kod.
Justin

4
@ m.buettner odpowiedzi można najpierw przetestować na inne odpowiedzi (na inne pytania), a następnie opublikować, a następnie edytować, aby zmienić adres URL :)
aditsu

8
@ hexafraction, jeśli komentarze mogą kolidować z odpowiedzią, to odpowiedź nie jest zbyt dobra ...
aditsu

17
Pytanie utknęło mi w głowie: jak napisać tweet, który prowadzi do siebie bez użycia skracaczy URL, ale oceniając tweet id twoim tweetem?
Ming-Tang

Odpowiedzi:


34

Bash + coreutils + przeglądarka Lynx, 61 bajtów

Dzięki @FDinoff za wskazówki:

lynx -dump codegolf.stackexchange.com/posts/28164/body|grep 2

4
A co się stanie, jeśli wpisam to magiczne słowo grep?
Cień

3
ryś ryś ryś ryś. Ten komentarz zostanie wyodrębniony (wraz z nagłówkiem)
ζ--

1
@hexafraction Awww. Musiałeś go zniszczyć!
Cień

8
Ten adres URL powinien działać. codegolf.stackexchange.com/posts/28164/bodyI ignoruje komentarze. Myślę też, że w granicach zasad można go używać ...
FDinoff

3
@DigitalTrauma awww ... cholera.
haneefmubarak

22

Rubinowy, 155 186 195 148 138 110 110 97 znaków

require'open-uri';puts open('http://codegolf.stackexchange.com/posts/28159/body').read[/req.+;/];

Musiałem zrobić z tego jedną linię, ponieważ w przeciwnym razie wyświetlałby nowe wiersze jako \nzamiast rzeczywistych nowych wierszy.

  • +31 znaków, ponieważ nie zauważyłem, że niektóre znaki uciekają.
  • +9 znaków, aby pozbyć się denerwującego ukośnika.
  • Podziękowania dla Nathana Osmana za uratowanie 2 znaków i Ventero za uratowanie 55 (!!!) poprzez usunięcie potrzeby większości poprawek wymienionych powyżej.

Wyjaśnienie

Upiększmy to najpierw. Będę jednak musiał użyć w tym kodzie nieco ... interesującej notacji. W tym poście nie mogę w ogóle używać średników, z powodów wyjaśnionych później, więc {SEMI}zamiast nich użyję średników.

require 'open-uri'
resp = open('http://codegolf.stackexchange.com/posts/28159/body').read
puts resp.match(/req.+{SEMI}/){SEMI}

Dobra, przejdźmy teraz przez to. Pierwsze dwa wiersze są dość zrozumiałe - pobierają tekst HTML tej odpowiedzi.

Ostatnia linia jest tutaj interesująca. Widzisz ten pozornie bezużyteczny średnik na końcu kodu? Jest to absolutnie wymagane i oto dlaczego.

Najpierw resp.matchwyodrębnia kod do wydrukowania. Regexp używa tego jest trick: /req.+{SEMI}/. Pobiera początek kodu, REQuire'net/http'szukając req( repobierze mój REputation). Następnie znajduje koniec kodu, szukając średnika! Ponieważ +domyślnie jest chciwy, będzie kontynuował, dopóki nie znajdzie średnika oznaczającego koniec kodu. Zobacz, dlaczego nie mogę już używać średników?

Po tym nie muszę niczego usuwać z scenografii, dzięki rozwiązaniu Ventero, które już nie używa \. Wszystko, co muszę zrobić, to {AMPERSAND}zmienić zmianę na {AMPERSAND}amp{SEMI}, co można osiągnąć po prostu usuwając amp{SEMI}część. Nie ma już takiej potrzeby z powodu nowego adresu URL. Następnie oryginalny kod został pobrany! (Uwaga: nie mogę również używać ampersand, ponieważ koduje się on w HTML, co powoduje utworzenie średnika).


Niektóre postacie uciekają ..
aditsu

1
@aditsu Gah; nie zauważyłem tego. Naprawiony.
Klamka

Nienawidzisz tego ... odwrotny ukośnik staje się powielany. Jest też różnica w nowej linii, ale to drobna sprawa.
aditsu

@aditsu Argh! : P Naprawiono również. Ta nowa linia jest spowodowana puts; można to naprawić za pomocą printmeh. Udawaj, że w kodzie jest końcowy znak nowej linii, nawet jeśli SE nie będzie w stanie go pokazać.
Klamka

1
Dla linku http://codegolf.stackexchange.com/a/28159dałby taki sam wynik jak twój i pozwoliłby zaoszczędzić trochę znaków.
Mhmd

20

PowerShell - 69 62

(irm codegolf.stackexchange.com/posts/28236/body).div.pre.code

DOM w powłoce. Miły!
fregante

Czy IRM nie wymaga usługi Azure Rights Management? Myślę, że bez tego modułu można to zrobić za pomocą Invoke-WebRequest.
Scott Leadley,

@ScottLeadley irmjest aliasem dla Invoke-RestMethodi został wprowadzony z rdzeniem PowerShell v3. computerperformance.co.uk/powershell/powershell3-alias.htm
Rynant

10
O kurczę. Odpowiedź na golfa w kodzie PowerShell o długości tego samego rzędu wielkości, co odpowiedzi wiodące. +1
Adam Maras

@AdamMaras Ha, wiem o co ci chodzi! To się czasem zdarza. codegolf.stackexchange.com/a/26811/4565 i codegolf.stackexchange.com/a/21982/4565 nie byli zbyt daleko od lidera.
Rynant

15

JavaScript - 123 122 101 95 92 91 87 86 114

with(new XMLHttpRequest)send(open(0,/\codegolf.stackexchange.com\posts\28175\body/,0)),alert(/w.*/.exec(response))

Działa w konsoli przeglądarki na tej stronie. Testowany na najnowszym Chrome i Firefox .

edycja: +28 bajtów, aby dodać pełną domenę.

Firefox nie lubi już mojej sztuczki z URL-em Regex dzięki tej aktualizacji :(

Oto przełomowe 86-bajtowe rozwiązanie:

with(new XMLHttpRequest)send(open(0,/posts\28175\body/,0)),alert(/w.*/.exec(response))

To mnie zachwyciło. Wiele razy.
fregante

1
@ bfred.it Właśnie wyciąłem bajt za pomocą interesującego wyrażenia regularnego. Mam nadzieję, że to sprawi, że jeszcze raz będziesz zachwycony.
nderscore

Jeśli drukowanie na konsoli jest akceptowalną metodą wydruku, możesz skrócić o 7 znaków, usuwając alert.
Tejas Kale

Ponadto, zgodnie z nową zasadą, musisz dodać codegolf.stackexchange.com/do adresu URL.
Tejas Kale

1
@TejasKale Z tego, co widziałem, ludzie krzywo patrzą na rozwiązania, które tak naprawdę nie ostrzegają / document.write / console.log odpowiedzi.
nderscore

10

Ruby + wget + gunzip , 159 86 82 71

Korzystanie z końcówki @FDinoff do użycia http://codegolf.stackexchange.com/posts/28173/body.

puts `wget -qO- codegolf.stackexchange.com/posts/28173/body`[/pu.*\]/]

Przetestowany. Dzięki @ace i @Bob za optymalizację wiersza poleceń.


2
Możesz łączyć flagi w wget, jak w wget -qO- url. Ponadto w bash nie potrzebujesz podwójnych cudzysłowów dla adresu URL, więc może to również działać dla Ciebie.
ace_HongKongIndependence

Możesz pominąć http://.
Bob

6

CJam - 53

"codegolf.stackexchange.com/posts/28184/body"g54/1=);


Tworzę tę wiki społeczności, ponieważ odpowiadam na własne pytanie i tak naprawdę nie chcę konkurować: p Kredyty dla FDinoff za wybór adresu URL.


Woot, +1 za uśmiechniętą twarz w kodzie
Cruncher

1
@Cruncher );nie wydaje mi się zbyt uśmiechnięty ...
MD XF

5

Rebmu, 91 znaków

Z powodu Catch-22 muszę pisać, aby uzyskać adres URL tej odpowiedzi. : - / Dobra, rozumiem.

paTSrd http://codegolf.stackexchange.com/a/28154[th<a name="28154">th<code>cpCto</code>]prC

Rebmu jest dialektem Rebola i możesz o nim przeczytać . Odpowiednikiem Rebola tutaj byłoby:

parse to-string read http://codegolf.stackexchange.com/a/28154 [
    thru <a name="28154">
    thru <code>
    copy c to </code>
]
print c

Rebol's PARSE jest rodzajem bardzo kompetentnej odpowiedzi na RegEx. Zaczyna pozycję parsera wejścia (która może być dowolną serią, w tym blokami strukturalnymi ... danymi binarnymi ... lub typami ciągów) . Reguły są językiem, w jaki sposób zmienia się pozycja analizy.

Tagi i adresy URL są w rzeczywistości po prostu napisami pod maską w języku. Ale są „doprawione”, a ponieważ Rebol jest dynamicznie wpisywany, możesz sprawdzić ten typ. READ na przykład wie, że jeśli podasz mu ciąg o smaku URL, to powinien wysłać do programu obsługi schematu, aby dokonać odczytu. (W tym przypadku zarejestrowany dla HTTP). Domyślnie odzyskujesz bajty UTF-8, więc używamy to-string, aby to zdekodować i uzyskać serię punktów kodowych w normalnym ciągu Unicode.

W przypadku dialektu parsowania napotkanie typu znacznika jest po prostu dopasowane, tak jakby był łańcuchem wyglądającym jak znacznik. THRU jest instrukcją oznaczającą „przeskocz do momentu dopasowania wynikającej z niej reguły, a następnie umieść pozycję dopasowania na końcu tego, co właśnie dopasowałeś”. (TO jest analogiem, który pasuje, ale pozostawia pozycję analizy przed elementem).

Pędzimy więc obok <a name="28154">. Następnie przeskakujemy obok następnego wystąpienia <code>, a nasza pozycja analizy jest teraz zlokalizowana zaraz po >. Polecenie PARSE COPY pozwala nam następnie skopiować dane do innej reguły, w tym przypadku reguła ta jest [TO </code>]... więc wchodzimy do zmiennej C wszystko do samego początku <.

Fajnie , co? :-)

Technicznie rzecz biorąc, mógłbym bardziej się ogolić, na przykład szukając, TO "</"a to oszczędza trzy postacie - nie trzeba dopasowywać całego </code>tagu końcowego, gdy tylko </to zrobi. Podobne argumenty można by podać dla tagu początkowego. Ale w Rebmu chodzi o umiejętność gry w golfa ... nawet jeśli początkowo wydaje Ci się, że wygląda dziwnie!

AKTUALIZACJA : /bodysztuczka jest wyjęta z torby, ale podobnie pozostawiam ją taką, jaka jest ... ponieważ myślę, że w ten sposób jest bardziej edukacyjna.


5

Java teraz 634, 852, miała 1004

Kod został zaktualizowany; dzięki za sugestie. Gra w golfa: teraz zamienia & gt na>

//bacchus
package golf;
import java.net.*;
import java.util.*;
public class G{
public static void main(String[] a) throws Exception {
Scanner z;
URL u;
int x=0;
String s;
u=new URL("http://codegolf.stackexchange.com/questions/28154/write-a-program-that-downloads-itself");
z=new Scanner(u.openConnection().getInputStream());
z.useDelimiter("\\s*//bacchus\\s*");
while(z.hasNext())
{
s=z.next();
s=s.replace("&gt;", ">");
if(x>0)System.out.println("//bacchus\n"+s);
x++;
if(x>2)break;
}
System.out.println("//bacchus\n");
}
}
//bacchus

Poddając się testom, dokonam edycji i wkrótce spróbuję zagrać w golfa. Musiałem zmienić x> 1 na x> 2, ponieważ ciąg testowy jest również w moim kodzie. Uwaga: Code golf zastępuje> symbol na & gt.

//bacchus
package golf;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class Golf {

    public static void main(String[] args) throws IOException {
        URL u;
        URLConnection c;
        InputStream i;
        InputStreamReader r;
        BufferedReader b;
        String s;
        int x=0;
        try {
            u=new URL("http://codegolf.stackexchange.com/questions/28154/write-a-program-that-downloads-itself");
            c=u.openConnection();
            i=c.getInputStream();
            r=new InputStreamReader(i);
            b=new BufferedReader(r);
            while((s=b.readLine())!=null)
            {
                if(s.contains("//bacchus")) x++;
                if(x>0)System.out.println(s);
                if(x>2) break;
            }
            i.close();
            b.close();
        } catch (MalformedURLException ex) {

        }
    }

}
//bacchus

7
Jak radzisz sobie z komentarzami zawierającymi //bacchus?
ζ--

3
Możesz wstawić wiele rzeczy, wypróbować z zasobami i użyć *importów, aby zaoszczędzić dużo kodu.
Simon Kuang

@ SimonKuang - Po prostu zostawię otwarte strumienie, a nie zamykam rzeczy. Ponadto throws Exceptionzamiast próbować sobie z czymkolwiek poradzić. Myślę też, że użycie skanera zamiast buforowanego czytnika byłoby prostsze, zwłaszcza że można ustawić ogranicznik na //bacchus, co ułatwiłoby trochę ...
Jules

5

Python, 175 167 bajtów

Wykorzystuje dwie biblioteki zewnętrzne; Nie przeczytałem, że to nieautoryzowane.

import bs4,requests
print(bs4.BeautifulSoup(requests.get('http://codegolf.stackexchange.com/q/28154').text).select('#answer-28171')[0].select('pre > code')[0].string)

Dłuższy, ale ładniejszy kod:

import bs4, requests
request = requests.get('http://codegolf.stackexchange.com/q/28154')
soup = bs4.BeautifulSoup(request.text)
answer = soup.select('#answer-28171')[0]
code = answer.select('pre > code')[1].string
print(code)

1
questionsW url można zastąpić q:http://codegolf.stackexchange.com/q/28154
Justin

1
Spację w bs4, requests(wiersz 1) można usunąć, aby zmniejszyć 1 bajt.
ace_HongKongIndependence

5

JavaScript, 228

r=new XMLHttpRequest()
c='code'
r.open('GET','//'+c+'golf.stackexchange.com/posts/28157/body')
r.onreadystatechange=function(){this.readyState==4&&alert((a=r.responseText).substr(i=a.indexOf(c)+5,a.indexOf('/'+c)-i-1))}
r.send()

Działa na tej stronie.


Jak to działa?
aditsu

@aditsu To ma być uruchamiane na konsoli JavaScript przeglądarki. Ale wciąż
testuję

@aditsu Powinno już działać. Otwórz konsolę przeglądarki (naciśnij F12) i wklej tam ten kod.
ace_HongKongIndependence

proszę pana, potrzebujecie if(this.readyState == this.DONE)funkcji.
Fabricio

1
@ace Widzę :) Do tej pory nie widziałem odpowiedzi innych js. W takim razie weź to ode mnie
głosowanie

4

Haskell, 563 613 bajtów

import Control.Monad
import Data.List
import Network.HTTP
m%f=join(fmap f m)
q s=(simpleHTTP(getRequest"http://codegolf.stackexchange.com/questions/28154/write-a-program-that-downloads-itself?answertab=oldest#tab-top"))%getResponseBody%(putStrLn.head.filter((==)(s++show s)).map(take 613).tails)
main=q"import Control.Monad\nimport Data.List\nimport Network.HTTP\nm%f=join(fmap f m)\nq s=(simpleHTTP(getRequest\"http://codegolf.stackexchange.com/questions/28154/write-a-program-that-downloads-itself?answertab=oldest#tab-top\"))%getResponseBody%(putStrLn.head.filter((==)(s++show s)).map(take 613).tails)\nmain=q"

Przetestowany. Obsługuje strony poprzez funkcję „najstarszych postów”. Używa struktury linii quine, aby znaleźć to, co wydrukować. Jest import Control.Monadtak tylko dlatego, że >>=generuje &gt;w HTML.


4

JavaScript + jQuery, 87 , 67

Nie jestem pewien, czy wolno mi używać jQuery, ale:

$('body').load('//codegolf.stackexchange.com/posts/28268/body pre')

JavaScript + jQuery, jeśli nie zaznaczono na tej stronie: 27 , 25

Dla zabawy, jeśli byłoby to tutaj wykonane:

$('[id$=268] pre').html()

$('[id$=28268] pre').html()


1
To daje więcej niż kod źródłowy.
nderscore

1
67:$('body').load('//codegolf.stackexchange.com/posts/28268/body pre')
nderscore

Masz rację, błędnie przyjąłem całą odpowiedź zamiast kodu
Martijn


3

Dart, 164

Myślałem, że spróbuję tego w Dart, fajnie jest używać imo.

Można to uruchomić w konsoli DartEditor, ale wymaga pakietu http dodanego w pubspec.yaml

import"package:http/http.dart"as h;h.read("http://codegolf.stackexchange.com/posts/28215/body").then((s){print(new RegExp(r"im.+(?:})").firstMatch(s).group(0));});}

Wersja bez golfa:

import "package:http/http.dart" as h;

void main()
{
  h.read("http://codegolf.stackexchange.com/posts/28215/body").then((s)
  {
    print(new RegExp(r"im.+(?:})").firstMatch(s).group(0));
  });
}

2

R 114 znaków

library(XML);cat(xpathSApply(xmlParse("http://codegolf.stackexchange.com/posts/28216/body"),'//code',xmlValue)[1])

Nie ma tu żadnej magii: pobiera wartość pola między tagami HTML <code></code>. Korzysta z biblioteki XML(co widać w kodzie dość wyraźnie). Wysyła wynik jako standardowe wyjście.


1

Java, 300 294

import java.net.*;import java.util.*;public class G{public static void main (String [] a) throws Exception{Scanner s=new Scanner(new URL("http://codegolf.stackexchange.com/posts/28189/body").openConnection().getInputStream()).useDelimiter("./?[c]ode\\W");s.next();System.out.print(s.next());}}

Ulepszona wersja odpowiedzi Bacchusbeale, która:

  • nie zamyka niepotrzebnie zasobów
  • nie deklaruje niepotrzebnych zmiennych
  • używa a, Scanneraby uniknąć konieczności zapętlenia wejścia
  • używa wyrażenia regularnego, które nie pasuje do siebie, aby uniknąć konieczności pominięcia środkowego wystąpienia znacznika początkowego / końcowego.

Zaktualizowano:

  • Użyj bezpośredniego adresu URL posta, więc nie potrzebujemy unikalnego komentarza, aby zidentyfikować początek / koniec kodu; używa teraz <code>[...]</code>jako ograniczników do wyszukiwania (w rzeczywistości używa wyrażenia regularnego „./?[c]ode\W”, aby uniknąć konieczności dekodowania &lt;i &gt;- konieczne jest „\ W” zamiast krótszego „.” aby uniknąć dopasowania części adresu URL do postu, niestety, która kosztuje 2 znaki, a nawiasy kwadratowe wokół c uniemożliwiają dopasowanie wyrażenia regularnego).

1
Masz mnóstwo niepotrzebnych miejsc. Twoja klasa nie musi być publiczna.
aditsu

1
openConnection (). getInputStream () można również skrócić do openStream ()
aditsu

1

w3m 55 bajtów

w3m codegolf.stackexchange.com/posts/28242/body|grep x

Na podstawie @DigitalTrauma


1

Ruby, 237 215 146 132

require'mechanize'
a=Mechanize.new
puts a.get('http://codegolf.stackexchange.com/a/28159').search('.lang-rb code:nth-child(1)').text

Jestem pewien, że możesz usunąć kilka spacji tu i tam, aby zaoszczędzić kilka bajtów.
MisterBla,

@richard, kogo to obchodzi, i tak nie wygram.
Mhmd

1
Zrób to dla loli, a nie dla wygranej.
MisterBla

@RichardA zrobione, a także usunąłem kilka znaków z wyrażenia regularnego.
Mhmd

1

Przetwarzanie, 90

print(loadStrings("http://codegolf.stackexchange.com/posts/28657/body")[2].substring(11));

Edycja: Nareszcie mam!



0

JavaScript, 138

a=window.open("http://codegolf.stackexchange.com/posts/28160/body");setTimeout('alert(a.document.body.innerHTML.match(/a=.*9\\)/)[0])',99)

Działa to przy założeniu, że strona ładuje się w czasie krótszym niż 99 ms. Musi być również uruchamiany za pomocą konsoli otwartej na stronie codegolf.SE, z powodu tej samej zasady pochodzenia.


Tylko uwaga: nie potrzebujesz ślimaka w adresie URL, a pytania można zastąpić q.
Schizm

1
Zauważ, że możesz to zrobić http://codegolf.stackexchange.com/a/28160zamiasthttp://codegolf.stackexchange.com/a/28160/12551
Justin

Chrome nie lubi tego: „
Nieprawidłowy typ błędu

@ Dalej należy wyłączyć blokowanie wyskakujących okienek.
nderscore

0

Perl 5.10, 155 127 122 117 bajtów

use XML::LibXML;say XML::LibXML->new->parse_file('http://codegolf.stackexchange.com/posts/28330/body')->find('//pre')

Korzystanie XML::LibXML.


0

Shell i xmllint, 82 bajty

xmllint --xpath 'string(//pre)' http://codegolf.stackexchange.com/posts/28333/body

0

Python, 164

Działa poprzez wyodrębnianie tekstu między znacznikami kodu. Jest dość długi, ale zawsze będzie działał poprawnie, chyba że strona HTML zostanie edytowana bezpośrednio lub nowy blok kodu zostanie dodany przed blokiem poniżej (posiadanie bloku kodu później nie powinno mieć wpływu na wynik programu).

import urllib2
print urllib2.urlopen("http://codegolf.stackexchange.com/posts/28617/body").read().split(chr(60)+"code"+chr(62))[1].split(chr(60)+"/code"+chr(62))[0]
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.