Напишите программу, которая сама загружает


66

Напишите программу, которая подключается к этому сайту, загружает сам ответ, в котором он размещен, извлекает собственный исходный код и распечатывает его. Вывод должен быть идентичен исходному коду. Самый короткий код (в байтах) выигрывает.

Правила:

  • Сокращения URL не допускаются.
  • Ответ должен иметь обычный формат - заголовок с названием и размером языка, необязательное описание, блок кода, необязательное описание и пояснение. Не допускаются неестественные разделители.
  • Вывод должен происходить из фактического блока кода, размещенного на сайте.
  • Функциональность не должна зависеть от позиции в списке ответов; это должно работать, даже если есть несколько страниц, и ответьте не на первой.
  • Новое: специальное примечание для ответов, которые должны запускаться в браузере: можно требовать их запуска в домене codegolf (для соблюдения политики того же источника), но домен и путь должны быть включены в решение, чтобы сделай это честным

39
Уловка-22: Как я должен проверить свою заявку?
Мартин Эндер

9
Я предполагаю, что люди публикуют ответы и удаляют их, чтобы они могли проверить свой код.
Джастин

4
@ m.buettner ответы можно сначала проверить на другие ответы (на другие вопросы), затем опубликовать, а затем отредактировать для изменения URL-адреса :)
aditsu

8
@hexafraction, если комментарии могут помешать ответу, тогда ответ не очень хороший ...
aditsu

17
У меня в голове застрял вопрос: как написать твит, который ссылается на себя, не используя сокращатели URL, а оценивая твит по твоему твиту?
Мин-Тан

Ответы:


34

Bash + coreutils + Lynx browser, 61 байт

Спасибо @FDinoff за советы:

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

4
И что произойдет, если я наберу это волшебное слово, которое ищет grep?
тень

3
рысь рысь рысь рысь Этот комментарий будет выделен (и заголовок также)
ζ--

1
@hexafraction Awww. Вы должны были пойти и разрушить это!
тень

8
Этот URL должен работать. codegolf.stackexchange.com/posts/28164/bodyИ это игнорирует комментарии. Я также думаю, что это в рамках правил, что вы можете использовать его ...
FDinoff

3
@DigitalTrauma AWww ... черт.
haneefmubarak

22

Рубин, 155 186 195 148 138 110 97 символов

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

Я должен был сделать это одной строкой, потому что в противном случае он выводил бы новые строки \nвместо реальных.

  • +31 символов, потому что я не заметил, что некоторые символы сбежали.
  • +9 символов, чтобы избавиться от надоедливой обратной косой черты.
  • Спасибо Натану Осману за сохранение 2 символов и Ventero за сохранение 55 (!!!), устраняя необходимость в большинстве исправлений, перечисленных выше.

Объяснение

Давайте сначала немного украсим это. Тем не менее, я собираюсь использовать несколько ... интересные обозначения в этом коде. Я не могу использовать точки с запятой в этом посте по причинам, объясненным позже, поэтому {SEMI}вместо них буду использовать точку с запятой.

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

Хорошо, теперь давайте пройдемся по этому. Первые две строки говорят сами за себя - они получают HTML-текст этого ответа.

Теперь последняя строка интересная здесь. Вы видите эту, казалось бы, бесполезную точку с запятой в конце кода? Это абсолютно необходимо, и вот почему.

Сначала resp.matchизвлекает код для печати. Регулярное выражение он использует для этого трюк: /req.+{SEMI}/. Он захватывает начало кода, REQuire'net/http'ища req( reзахватил бы мой REputation). Затем он находит конец кода путем поиска точки с запятой! Поскольку +по умолчанию он является жадным, он будет продолжать работать до тех пор, пока не найдет точку с запятой, обозначающую конец кода. Видишь, почему я больше не могу использовать точки с запятой?

После этого мне не нужно ничего убирать из-за исправления, которое Ventero больше не использовал \. Все , что я должен сделать , это исправить {AMPERSAND}изменения в {AMPERSAND}amp{SEMI}, которое может быть достигнуто лишь путем удаления amp{SEMI}части. Нет необходимости в этом из-за нового URL. После этого исходный код был восстановлен! (Примечание: я тоже не могу использовать амперсанд, потому что он кодируется HTML, что приводит к созданию точки с запятой.)


Некоторым персонажам
удается

1
@aditsu Gah; не заметил этого Исправлена.
Дверная ручка

Ты будешь ненавидеть это ... обратный слеш дублируется. Есть также разница в новой строке, но это мелочь.
aditsu

@aditsu Argh! : P Исправлено также. Новая строка из-за puts; это может быть исправлено, printно Мех. Просто представьте, что в коде есть завершающий символ новой строки, хотя SE не сможет его показать.
Дверная ручка

1
Для ссылки, http://codegolf.stackexchange.com/a/28159даст тот же результат, что и ваш, и сэкономит некоторые символы.
Mhmd

20

PowerShell - 69 62

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

ДОМ в оболочке. Приятно!
Фреганте

Разве не требуется управление правами Azure? Без этого модуля, я думаю, вы могли бы сделать это с помощью Invoke-WebRequest.
Скотт Лидли

@ScottLeadley irm- псевдоним для Invoke-RestMethodи был представлен с ядром PowerShell v3. computerperformance.co.uk/powershell/powershell3-alias.htm
Rynant

10
Святое дерьмо. Гольф-ответ PowerShell с длиной в том же порядке, что и ведущие ответы. +1
Адам Марас

@AdamMaras Ха, я знаю, что ты имеешь в виду! Это случается иногда, хотя. codegolf.stackexchange.com/a/26811/4565 и codegolf.stackexchange.com/a/21982/4565 были не слишком далеко от лидера.
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))

Запускается в консоли вашего веб-браузера на этой странице. Проверено на последних версиях Chrome и Firefox .

изменить: +28 байт, чтобы добавить полный домен.

Firefox больше не нравится мой трюк с Regex URL с этим обновлением :(

Вот 86-байтовое решение, нарушающее правила:

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

Это заставило меня трепетать. Много раз.
Фреганте

1
@ bfred.it Я просто вырезал байт, используя интересное регулярное выражение. Я надеюсь, что это заставит вас трепетать еще раз.
nderscore

Если печать на консоль является приемлемым методом вывода, вы можете сократить на 7 символов, удалив предупреждение.
Теджас Кале

Кроме того, согласно новому правилу, вы должны добавить codegolf.stackexchange.com/к URL.
Теджас Кале

1
@TejasKale Из того, что я видел, люди недовольны решениями, которые фактически не предупреждают / document.write / console.log ответ.
nderscore

10

Ruby + Wget + Gunzip , 159 86 82 71

Используя подсказку @FDinoff для использования http://codegolf.stackexchange.com/posts/28173/body.

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

Проверено. Спасибо @ace и @Bob за оптимизацию командной строки.


2
Вы можете комбинировать флаги wget, как в wget -qO- url. Кроме того, в bash вам не нужны двойные кавычки для URL, так что это также может работать для вас.
ace_HongKongIndependence

Вы можете опустить http://.
Боб

6

CJam - 53

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

Я делаю это сообщество вики, так как отвечаю на свой вопрос и не хочу участвовать в конкурсе: p
Кредиты FDinoff для выбора URL.


Woot, +1 для смайлика в коде
Cruncher

1
@Cruncher );не выглядит слишком улыбчивым для меня ...
MD XF

5

Ребму, 91 персонаж

Из-за Catch-22 я должен опубликовать, чтобы получить URL этого ответа. :-/ Хорошо, понял.

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

Rebmu это диалект Rebol, и вы можете прочитать все о нем . Эквивалент Rebol здесь будет:

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

PARSE от Rebol - это своего рода очень грамотный ответ для RegEx. Он запускает позицию парсера ввода (это может быть любая последовательность, включая структурные блоки ... двоичные данные ... или строковые типы) . Правила являются языком для того, как перемещается позиция разбора.

Теги и URL-адреса - это всего лишь строки в языке. Но они «приправлены», и поскольку Rebol динамически набирается, вы можете проверить этот тип. Например, READ знает, что если вы дадите ей строку со вкусом URL, то он должен отправить ее обработчику схемы для чтения. (В этом случае тот, который зарегистрирован для HTTP). По умолчанию вы возвращаете байты UTF-8, поэтому мы используем to-string для его декодирования и получения серии кодовых точек в обычной строке Unicode.

В случае диалекта синтаксического анализа встреча с типом тега просто сопоставляется, как если бы это была строка, похожая на тег. THRU - это инструкция, означающая «пропустить, пока не будет найдено соответствующее правило, а затем поместить позицию соответствия в конец того, что вы только что сопоставили». (TO является аналогом, который соответствует, но оставляет позицию разбора перед элементом).

Таким образом, мы пронесемся мимо <a name="28154">. Затем мы пронесемся мимо следующего вхождения <code>, с нашей позицией синтаксического анализа, расположенной сразу после >. Затем команда PARSE COPY позволяет нам копировать данные в другое правило, в данном случае это правило [TO </code>]... так что мы попадаем в переменную C все вплоть до этого <.

Круто , а? :-)

С технической точки зрения я мог бы TO "</"сэкономить на этом больше, например, путем поиска и сохранения трех символов - нет необходимости сопоставлять весь </code>конечный тег, когда это </можно сделать. Подобные аргументы могут быть приведены для начального тега. Но Rebmu о грамотном гольфе ... даже если вы думаете, это поначалу выглядит странно!

ОБНОВЛЕНИЕ : /bodyуловка из сумки, но я также собираюсь оставить это как есть ... потому что я думаю, что это более образовательно в этом смысле.


5

Ява сейчас 634, 852, было 1004

Код был обновлен; спасибо за предложения. Гольф: теперь заменяет & gt на>

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

Отправляя на тестирование, я скоро отредактирую и попробую сыграть в гольф. Необходимо изменить x> 1 на x> 2, потому что тестовая строка также есть в моем коде. Примечание. Код гольф заменяет символ> на & 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
Как вы обрабатываете комментарии, содержащие //bacchus?
ζ--

3
Вы можете встроить много вещей, попробовать с ресурсами и использовать *импорт для сохранения большого количества кода.
Симон Куанг

@SimonKuang - я бы просто оставлял потоки открытыми, а не закрывал. Кроме того, throws Exceptionвместо того, чтобы пытаться справиться с чем-либо. Кроме того, я думаю, что использование Scanner, а не BufferedReader было бы проще, особенно если бы вы могли установить разделитель //bacchus, что несколько упростит задачу ...
Жюль

5

Python, 175 167 байт

Это использует две внешние библиотеки; Я не читал, что это было несанкционировано.

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

Более длинный, но более красивый код:

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
В questionsURL можно заменить на q:http://codegolf.stackexchange.com/q/28154
Джастин

1
Пробел в bs4, requests(строка 1) может быть удален, чтобы уменьшить 1 байт.
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()

Работает на этой странице.


Как вы управляете этим?
aditsu

@aditsu Предполагается, что он будет запущен на консоли JavaScript браузера. Но я все еще тестирую (и исправляю), пожалуйста, подождите
ace_HongKongIndependence

@aditsu Это должно работать сейчас. Откройте консоль браузера (нажмите F12) и вставьте туда этот код.
ace_HongKongIndependence

Вы, сэр, нужна if(this.readyState == this.DONE)внутренняя функция.
Fabricio

1
@ Вижу, я вижу :) Я не видел другой ответ JS до сих пор. Тогда возьми от меня это возражение
C5H8NNaO4

4

Haskell, 563 613 байт

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"

Проверено. Имеет поддержку страницы через функцию «старые сообщения». Использует структуру quine-line, чтобы найти, что печатать. Это import Control.Monadтолько потому, что >>=генерируется &gt;в HTML.


4

Javascript + JQuery, 87 , 67

Я не уверен, что мне разрешено использовать jQuery, но:

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

Javascript + jQuery, если не указано на этой странице: 27 , 25

Ради интереса, если бы это было приведено здесь:

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

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


1
Это выводит больше, чем исходный код.
nderscore

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

Вы правы, я неправильно посчитал весь ответ вместо кода
Martijn

4

w3m 45 символов

w3m codegolf.stackexchange.com/a/28336|grep ☻

1
☺. Это все еще работает? Редактировать: похоже, что это делает.
ace_HongKongIndependence

@ace, я получаю ваш комментарий, когда я запускаю его
FDinoff

Исправлено :) Кто-нибудь еще? G
gnibbler

3

Дротик, 164

Я думал, что попробую это в Dart, довольно забавно использовать IMO.

Это можно запустить в консоли в DartEditor, но для этого требуется пакет http, добавленный в 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));});}

Безголовая версия:

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 символов

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

Здесь нет ничего особенного: он принимает значение поля между тегами html <code></code>. Использует библиотеку XML(как видно из кода вполне очевидно). Выводит результат как стандартный вывод.


1

Ява, 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());}}

Улучшенная версия ответа bacchusbeale, который:

  • не закрывает ресурсы без необходимости
  • не объявляет ненужные переменные
  • использует, Scannerчтобы избежать необходимости зацикливать на входе
  • использует регулярное выражение, которое не соответствует самому себе, чтобы избежать пропуска среднего вхождения маркера начала / конца.

Обновлено:

  • Используйте прямой URL к сообщению, поэтому нам не нужен уникальный комментарий для определения начала / конца кода; теперь использует <code>[...]</code>в качестве разделителей для поиска (фактически используя регулярное выражение "./?[c]ode\W", чтобы избежать необходимости декодирования &lt;и &gt;- "\ W" необходим, а не короче "." к сожалению, чтобы избежать совпадения части URL-адреса с сообщением, которое стоит 2 символа, а квадратные скобки вокруг c предотвращают сопоставление регулярного выражения).

1
У вас есть куча ненужных пробелов. Также ваш класс не должен быть публичным.
aditsu

1
openConnection (). getInputStream () также может быть сокращено до openStream ()
aditsu

1

w3m 55 байт

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

Основано на @DigitalTrauma


1

Рубин, 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

Уверен, вы можете удалить несколько пробелов тут и там, чтобы сэкономить несколько байтов.
MisterBla

@ Ричард, кого это волнует, я все равно не выиграю.
Mhmd

1
Делай это ради веселья, а не для победы.
MisterBla

@RichardA готово, и я также удалил несколько символов из регулярного выражения.
Mhmd

1

Обработка, 90

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

Редактировать: наконец-то получил!


1

bash + awk, 71 байт

curl -sL codegolf.stackexchange.com/q/28154 |awk -F\> '/\#/ {print $3}'

2
Кажется, не работает - он выводит много других вещей вместе с этим ответом.
Riking

@ Правильно, похоже, что это зависит от позиции (нарушая последнее правило)
aditsu

Вы можете опустить http://.
Боб

@ user155406: обратите внимание, что у каждого ответа есть URL-адрес - это codegolf.stackexchange.com/a/28179/14710
Фил Х,

0

Javascript, 138

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

Это работает при условии, что страница загружается менее чем за 99 мс. Он также должен запускаться через консоль, открытую на странице codegolf.SE, из-за той же политики происхождения.


Просто примечание: вам не нужен фрагмент в URL, и вопросы можно заменить на q.
Раскол

1
Обратите внимание, что вы могли бы сделать http://codegolf.stackexchange.com/a/28160вместоhttp://codegolf.stackexchange.com/a/28160/12551
Джастин

Chrome не нравится это: «Uncaught TypeError: Невозможно прочитать свойство 'document' of undefined"
Spedwards

@ Вскоре вы должны отключить блокировку всплывающих окон.
nderscore

0

Perl 5.10, 155 127 122 117 байт

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

Использование XML::LibXML.


0

Shell и xmllint, 82 байта

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

0

Питон, 164

Работает, извлекая текст между тегами кода. Он довольно длинный, но он всегда будет работать правильно, если html-страница не будет отредактирована напрямую или новый кодовый блок не будет добавлен перед нижеследующим (наличие блока кода после не должно влиять на вывод программы).

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]
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.