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.
aditsu
fonte
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
Trauma Digital
fonte
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.)

Maçaneta da porta
fonte
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
Rynant
fonte
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))
nderscore
fonte
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.

dtldarek
fonte
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.

aditsu
fonte
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.

Dr. Rebmu
fonte
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
bacchusbeale
fonte
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)
MeldSnake
fonte
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.

ace_HongKongIndependence
fonte
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.

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

Martijn
fonte
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
4

w3m 45 caracteres

w3m codegolf.stackexchange.com/a/28336|grep ☻
mordedor
fonte
11
☺ Ainda funciona? Edit: Parece que sim.
ace_HongKongIndependence
@ace I obter o seu comentário quando eu executá-lo
FDinoff
Corrigido :) Mais alguém? G
gnibbler
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));
  });
}
MisterBla
fonte
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.

plannapus
fonte
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).
Jules
fonte
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

Moop
fonte
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
Mhmd
fonte
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!

segfaultd
fonte
1

bash + awk, 71 bytes

curl -sL codegolf.stackexchange.com/q/28154 |awk -F\> '/\#/ {print $3}'
user155406
fonte
2
Parece não funcionar - gera muitas outras coisas junto com esta resposta.
Riking
@Riking verdade, parece ser dependente da posição (quebrando a última regra)
aditsu
Você pode deixar de fora o http://.
22414 Bob
@ user155406: note que cada resposta tem um URL - este é codegolf.stackexchange.com/a/28179/14710
Phil H
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.

Zaq
fonte
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.

Nwellnhof
fonte
0

Shell e xmllint, 82 bytes

xmllint --xpath 'string(//pre)' http://codegolf.stackexchange.com/posts/28333/body
Nwellnhof
fonte
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]
icedvariables
fonte