Escreva um programa que faça o download por si próprio


66

Escreva um programa que se conecte a este site, baixe a própria resposta em que é publicado, extraia seu próprio código-fonte e o imprima. A saída deve ser idêntica ao código fonte. O código mais curto (em bytes) vence.

Regras:

  • Não são permitidos encurtadores de URL.
  • A resposta deve ter um formato regular - um cabeçalho com o nome e o tamanho do idioma, descrição opcional, bloco de código, descrição e explicação opcionais. Não são permitidos delimitadores não naturais.
  • A saída deve se originar do bloco de código real publicado no site.
  • A funcionalidade não deve depender da posição na lista de respostas; deve funcionar mesmo se houver várias páginas e a resposta não estiver na primeira.
  • Novo: nota especial para respostas que devem ser executadas em um navegador: não há problema em executá-las no domínio codegolf (para obedecer à política de mesma origem), mas o domínio e o caminho devem ser incluídos na solução para faça justo.

39
Catch-22: Como devo testar minha inscrição?
Martin Ender

9
Vejo pessoas postando respostas e excluindo-as, para que possam testar seu código.
187 Justin Justin

4
@ respostas m.buettner pode ser testado em outras respostas (a outras perguntas) em primeiro lugar, em seguida, postou, então editados para alterar a URL :)
aditsu

8
@hexafraction se os comentários são capazes de interferir com uma resposta, então a resposta não é muito bom ...
aditsu

17
Uma pergunta ficou na minha cabeça: como escrever um tweet vinculado a si mesmo sem usar encurtadores de URL, mas estimando o id do tweet?
Ming-Tang

Respostas:


34

Navegador Bash + coreutils + Lynx, 61 bytes

Obrigado a @FDinoff pelas dicas:

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

4
E o que acontece se eu digitar a palavra mágica que grep está procurando?
Shade

3
lince lince lince lince. Este comentário será exibido (e também o cabeçalho) #
17/14

11
@hexafraction Awww. Você tinha que arruiná-lo!
Shade

8
Este URL deve funcionar. codegolf.stackexchange.com/posts/28164/bodyE ignora comentários. Eu também acho que dentro das regras que você pode usá-lo ...
FDinoff

3
@DigitalTrauma awww ... damn.
21714 haneefmubarak

22

Ruby, 155 186 195 148 138 138 110 97 caracteres

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

Eu tive que criar uma linha, porque, caso contrário, produziria novas linhas como em \nvez de novas linhas reais.

  • +31 caracteres porque eu não notei que alguns caracteres estavam sendo escapados.
  • +9 caracteres para se livrar da barra invertida irritante.
  • Agradecemos a Nathan Osman por salvar 2 caracteres e Ventero por salvar 55 (!!!) removendo a necessidade da maioria das correções listadas acima.

A explicação

Vamos embelezar isso um pouco primeiro. No entanto, vou ter que usar uma notação ... interessante neste código. Não posso usar ponto e vírgula neste post, por razões explicadas mais adiante; portanto, em vez disso, usarei {SEMI}no lugar de ponto e vírgula.

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

Tudo bem, agora vamos passar por isso. As duas primeiras linhas são bastante auto-explicativas - elas buscam o texto HTML desta resposta.

Agora, a última linha é a interessante aqui. Você vê esse ponto e vírgula aparentemente inútil no final do código? É absolutamente necessário, e aqui está o porquê.

Primeiro, resp.matchextrai o código a ser impresso. A expressão regular que ele usa para isso é o truque: /req.+{SEMI}/. Ele pega o início do código, REQuire'net/http'procurando por req( reiria pegar o meu REputation). Em seguida, ele encontra o final do código pesquisando um ponto e vírgula! Como +é ganancioso por padrão, ele continuará até encontrar o ponto-e-vírgula que significa o final do código. Veja por que não consigo mais usar ponto e vírgula?

Depois disso, não tenho mais que escapar, graças à correção de Ventero de não usar \mais. Tudo o que tenho a fazer é consertar a {AMPERSAND}mudança {AMPERSAND}amp{SEMI}, o que pode ser alcançado simplesmente removendo a amp{SEMI}peça. Não há mais necessidade disso por causa do novo URL. Depois disso, o código original foi recuperado! (Observação: também não posso usar o "e" comercial, porque ele é codificado em HTML, o que faz com que um ponto-e-vírgula seja criado.)


Alguns caracteres estão sendo escapados ..
aditsu 17/05

11
@aditsu Gah; não percebeu isso. Fixo.
Maçaneta

Você vai odiar isso ... uma barra invertida está sendo duplicada. Há também uma diferença de nova linha, mas isso é uma coisa menor.
aditsu 17/05

@aditsu Argh! : P Corrigido também. A coisa da nova linha é por causa de puts; poderia ser corrigido com printmas meh. Apenas finja que há uma nova linha no código, mesmo que o SE não consiga mostrá-la.
Maçaneta

11
Para o link, http://codegolf.stackexchange.com/a/28159daria o mesmo resultado que o seu e salvaria alguns caracteres.
Mhmd 19/05

20

PowerShell - 69 62

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

DOM em um shell. Agradável!
Fregante

Irm não requer Gerenciamento de Direitos do Azure? Sem esse módulo, acho que você poderia fazê-lo com Invoke-WebRequest.
Scott Leadley

@ScottLeadley irmé o alias para Invoke-RestMethode foi introduzido no núcleo do PowerShell v3. computerperformance.co.uk/powershell/powershell3-alias.htm
Rynant

10
Caralho. Uma resposta de golfe com código do PowerShell com um comprimento na mesma ordem de magnitude das respostas principais. +1
Adam Maras

@AdamMaras Ha, eu sei o que você quer dizer! Mas acontece ocasionalmente. codegolf.stackexchange.com/a/26811/4565 e codegolf.stackexchange.com/a/21982/4565 não estavam muito longe da liderança.
Rynant # 20/14

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

É executado no console do seu navegador nesta página. Testado no Chrome e Firefox mais recentes .

edite: +28 bytes para adicionar o domínio completo.

O Firefox não gosta mais do meu truque de URL Regex com esta atualização :(

Aqui está a solução inovadora de 86 bytes:

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

Isso me fez admirar. Várias vezes.
21414 fregante

11
@ bfred.it Acabei de cortar um byte usando um regex interessante. Espero que isso faça você se impressionar mais uma vez.
Nderscore #

Se a impressão no console for um método aceitável de saída, você poderá reduzir 7 caracteres removendo o alerta.
Tejas Kale

Além disso, de acordo com a nova regra, você deve adicionar codegolf.stackexchange.com/ao URL.
Tejas Kale

11
@TejasKale Pelo que vi, as pessoas desaprovam soluções que na verdade não alertam / document.write / console.log a resposta.
Ndscore # 19/14

10

Ruby + wget + gunzip , 159 86 82 71

Usando a dica de @FDinoff para usar http://codegolf.stackexchange.com/posts/28173/body.

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

Testado. Obrigado a @ace e @Bob pela otimização da linha de comando.


2
Você pode combinar as bandeiras wget, como em wget -qO- url. Além disso, no bash você não precisa de aspas duplas para o URL, portanto, isso também pode funcionar para você.
ace_HongKongIndependence

Você pode deixar de fora o http://.
Bob

6

CJam - 53

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

Estou criando este wiki da comunidade, pois estou respondendo à minha própria pergunta e realmente não quero competir: p
Créditos ao FDinoff pela escolha da URL.


Woot, um para a cara do smiley no código
Cruncher

11
@Cruncher );não parece muito risonho para mim ...
MD XF

5

Rebmu, 91 caracteres

Devido ao Catch-22, tenho que postar para obter o URL desta resposta. : - / Ok, entendi.

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

Rebmu é um dialeto de Rebol, e você pode ler tudo sobre ele . O Rebol equivalente aqui seria:

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

O PARSE da Rebol é uma espécie de resposta altamente alfabetizada ao RegEx. Inicia uma posição do analisador da entrada (que pode ser de qualquer série, incluindo blocos estruturais ... dados binários ... ou tipos de string) . As regras são um idioma para o movimento da posição de análise.

Tags e URLs são realmente apenas strings no idioma. Mas eles são "aromatizados" e, como o Rebol é digitado dinamicamente, você pode verificar esse tipo. Leia, por exemplo, sabe que, se você fornecer uma string com sabor de URL, ela deverá ser enviada para um manipulador de esquema para fazer a leitura. (Nesse caso, aquele registrado para HTTP). Como você recebe UTF-8 bytes por padrão, usamos a cadeia de caracteres para decodificar isso e obter uma série de pontos de código em uma cadeia Unicode normal.

No caso do dialeto de análise, encontrar um tipo de tag corresponde apenas como se fosse uma string que se parecesse com a tag. THRU é uma instrução que significa "pular até que a regra a seguir seja correspondida e, em seguida, coloque a posição da correspondência no final do que você acabou de corresponder". (TO é o análogo que corresponde, mas deixa a posição de análise antes do elemento).

Então, passamos pelo <a name="28154">. Em seguida, passamos pela próxima ocorrência de <code>, com nossa posição de análise agora localizada logo após a >. O comando COPY do PARSE nos permite copiar dados para outra regra, neste caso, essa regra é [TO </code>]... então entramos na variável C tudo até pouco antes disso <.

Legal , né? :-)

Tecnicamente, eu poderia TO "</"economizar mais, por exemplo, procurando e economizando três caracteres - não há necessidade de combinar com a </code>tag final quando </isso aconteceria. Argumentos semelhantes poderiam ser feitos para a tag start. Mas Rebmu é sobre golfe alfabetizado ... mesmo que você ache estranho no começo!

ATUALIZAÇÃO : o /bodytruque está pronto, mas da mesma forma vou deixar como está ... porque acho que é mais educativo dessa maneira.


5

Java agora 634, 852, era 1004

O código foi atualizado; obrigado por sugestões. Golfed: agora substitui & gt por>

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

Ao enviar para o teste, editarei e tentarei jogar em breve. Precisava alterar x> 1 para x> 2 porque a sequência de teste também está no meu código. Nota: O código golf substitui o símbolo> por & 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
Como você lida com os comentários que contêm //bacchus?
ζ--

3
Você pode incorporar várias coisas, tentar com recursos e usar *importações para economizar muito código.
Simon Kuang

@SimonKuang - eu também deixaria as correntes abertas em vez de fechar as coisas. Além disso, throws Exceptionao invés de tentar lidar com qualquer coisa. Além disso, eu acho que usando um scanner em vez de um BufferedReader seria mais simples, especialmente porque você pode definir o delimitador para //bacchus, o que tornaria as coisas um pouco mais fácil ...
Jules

5

Python, 175 167 bytes

Isso usa duas bibliotecas externas; Eu não li que não era autorizado.

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

Código mais longo, mas mais bonito:

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)

11
O questionsURL pode ser substituído por q: #http://codegolf.stackexchange.com/q/28154
Justin Justin

11
O espaço na bs4, requests(linha 1) pode ser removido para reduzir 1 byte.
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()

É executado nesta página.


Como você executa isso?
Aditsu 17/05/19

@aditsu Ele deve ser executado no console JavaScript de um navegador. Mas eu ainda estou testando (e corrigir)-lo, por favor espere
ace_HongKongIndependence

@aditsu Deve funcionar agora. Abra o console do navegador (pressione F12) e cole esse código lá.
ace_HongKongIndependence

senhor, precisa de uma if(this.readyState == this.DONE)função interna.
Fabricio

11
@ace vejo :) Eu não vi os outros js responder até agora. Então pegue este
voto positivo

4

Haskell, 563 613 bytes

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"

Testado. Possui suporte à página por meio do recurso "postagens mais antigas". Usa estrutura de linhas quinas para encontrar o que imprimir. O import Control.Monadé apenas porque >>=gera &gt;em HTML.


4

Javascript + jQuery, 87 , 67

Não tenho certeza se posso usar o jQuery, mas:

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

Javascript + jQuery, se for executado nesta página: 27 , 25

Por diversão, se seria executado aqui:

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

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


11
Isso gera mais que o código fonte.
Ndscore # 20/14

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

Você está correto, eu erroneamente asumed toda a resposta em vez do código
Martijn


3

Dardo, 164

Eu pensei que eu tentaria isso em Dart, é muito divertido de usar IMO.

Isso pode ser executado no console do DartEditor, mas requer o pacote http adicionado em 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));});}

Versão não destruída:

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 caracteres

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

Nenhuma mágica real aqui: leva o valor do campo entre as tags html <code></code>. Usa biblioteca XML(como se pode ver no código, obviamente). Produz o resultado como stdout.


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

Uma versão melhorada da resposta de bacchusbeale que:

  • não fecha recursos desnecessariamente
  • não declara variáveis ​​desnecessárias
  • usa a Scannerpara evitar ter que passar por cima da entrada
  • usa uma regexp que não corresponde a si mesma para evitar ter que pular uma ocorrência intermediária do marcador de início / fim.

Atualizada:

  • Use um URL direto para a postagem, para que não precisemos de um comentário exclusivo para identificar o início / fim do código; agora usa <code>[...]</code>como delimitadores para procurar (na verdade, usando a expressão regular "./?[cξode\W", para evitar ter que decodificar &lt;e &gt;- o "\ W" é necessário, e não o mais curto "." para evitar que ele corresponda parte do URL à postagem, infelizmente, que custa 2 caracteres, e os colchetes em torno de c impedem que o regex corresponda a si próprio).

11
Você tem um monte de espaços desnecessários. Além disso, sua turma não precisa ser pública.
Aditsu 19/05/2014

11
O openConnection (). getInputStream () também pode ser reduzido para openStream ()
aditsu

1

w3m 55 bytes

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

Baseado em @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

Certamente você pode remover alguns espaços aqui e ali para salvar alguns bytes.
MisterBla

@richard quem se importa, eu não vou ganhar de qualquer maneira.
Mhmd 19/05

11
Faça isso pelos risos, não por vencer.
MisterBla

@ Richardhard feito, e também removi alguns caracteres do regexp.
Mhmd 19/05

1

Processamento, 90

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

Edit: Finalmente entendi!



0

Javascript, 138

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

Isso funciona assumindo que a página carrega menos de 99 ms. Ele também deve ser executado através de um console aberto em uma página codegolf.SE, devido à mesma política de origem.


Apenas uma observação: você não precisa da lesma no URL e as perguntas podem ser substituídas por q.
Schism

11
Note que você poderia fazer em http://codegolf.stackexchange.com/a/28160vez dehttp://codegolf.stackexchange.com/a/28160/12551
Justin

O Chrome não gosta disso: "TypeError não capturado: não é possível ler a propriedade 'document' 'de undefined"
Spedwards

@Spedwards, você deve desativar o bloqueador de pop-ups.
Ndscore # 19/14

0

Perl 5.10, 155 127 122 117 bytes

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

Usando XML::LibXML.


0

Shell e xmllint, 82 bytes

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

0

Python, 164

Funciona extraindo o texto entre as tags de código. É bastante longo, mas sempre funcionará corretamente, a menos que a página html seja editada diretamente ou um novo bloco de código seja adicionado antes do abaixo (ter um bloco de código depois não deve afetar a saída do programa).

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]
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.