Створіть несправний браузер XKCD


75

Виклик

Враховуючи кількість коміксу XKCD, виведіть текст заголовка цього коміксу (текст миші).

Однак програма повинна видавати помилку, коли даються цифри 859або 404.

Правила

Дане число завжди буде існуючим коміксом (крім 404).

Ваша програма не повинна видавати помилки для будь-яких інших номерів, ніж 859або 404.

Для довідки, комічного 404не існує і 859є:

Brains aside, I wonder how many poorly-written xkcd.com-parsing scripts will break on this title (or ;;"''{<<[' this mouseover text."

Укорочувачі URL-адрес заборонені. Ви можете скористатися Інтернетом, щоб отримати текст заголовка.

Приклади

Input > Output
1642 > "That last LinkedIn request set a new record for the most energetic physical event ever observed. Maybe we should respond." "Nah."
1385 > ::PLOOOOSH:: Looks like you won't be making it to Vinland today, Leaf Erikson.
1275 > If replacing all the '3's doesn't fix your code, remove the 4s, too, with 'ceiling(pi) / floor(pi) * pi * r^floor(pi)'. Mmm, floor pie.
1706 > Plus, now I know that I have risk factors for elbow dysplasia, heartworm, parvo, and mange.

Баунті

Я присуджую винагороду за найкоротшу відповідь, яка не відповідає комічному 859, тому що вона погано написана замість перевірки на номер.

Ваша програма може перерватися на інші тексти alt (наприклад, 744) за умови, що вони мають невідповідні дужки, лапки тощо.

Перемога

Виграє найкоротший код у байтах.


2
Оскільки є й інші комікси з текстами альт-текстів, що розбиваються на сценарії (див. 744 ), чи добре, якщо програма теж перервана?
повністюлюдський

8
@totallyhuman До цього слід було б додати трохи NSFW-попередження: P
HyperNeutrino

11
Протиріччя у виклику: «не повинно видавати помилку для будь-яких інших чисел , ніж 859або 404» і «може зламатися на інших текстах альта».
aschepler

3
@aschepler Остання призначена лише для винагороди
Beta Decay

4
@Kzqai Добре запитання, але я думаю, ви, можливо, трохи недооцінюєте, скільки трафіку задіяно в DDOS, а також скільки трафіку xkcd.com вже має. Я б не очікував, що трафік, отриманий за допомогою відповідей тут, буде значним порівняно з будь-яким із них.
трихоплакс

Відповіді:


107

Python 2.7 + xkcd , 55 байт

xkcd - сторонній пакет Python. У Python є пакет для всього !

lambda n:[xkcd.getComic(n).altText][n==859]
import xkcd

Для 404: urllib2.HTTPError: HTTP Error 404: Not Found

Для 859: IndexError: list index out of range


89
Пакет був написаний перед цим викликом і не був написаний спеціально для цього виклику, він просто вкрай підходить.
Draco18s

4
Нічого собі, Python просто став привабливішим!
Nat


6
За збігом обставин, пітон дійсно підтримує import"ing" antigravity.
Ще один користувач

39
Хіба що Python тільки Mathematica це завдання?
Арктур

22

Python 2 + Requests , 104 102 95 94 байт

-2 байти завдяки Еріку Переможнику. -1 байт завдяки Джонатану Аллану.

lambda n:[get('http://xkcd.com/%d/info.0.json'%n).json()['alt']][n==859]
from requests import*

Обов’язкові:

import antigravity

Погано написаний сценарій, 98 байт

Отже, писати погані сценарії насправді важко зробити навмисно ... Це також порушується на інших коміксах, оскільки вони містять цитати, не впевнені, чи це нормально.

from requests import*
exec'print "%s"'%get('http://xkcd.com/%d/info.0.json'%input()).json()['alt']

4
Я думаю, ви можете зняти ,a.
Ерік Аутгольфер

1
Ви можете змінити , n in[404,859]щоб n==859, так як декодер JSON не вдається в 404будь-якому випадку.
музикант523

7
... http://можна використовувати і тут, я думаю.
Джонатан Аллан

1
як ти насправді запускаєш цей параметр? Мовляв, як ти заводиш безіменну лямбда?
MrZander

1
@MrZander Перший рядок - це анонімна лямбда, якій можна присвоїти змінну, яку потрібно запустити. Наприклад, обидва f = lambda n: n * 2; print f(2)або (lambda n: n * 2)(2)надрукують 4.
цілкомлюдсько

18

Python 2 + xkcd, 82 байти

Погано написаний сценарій

lambda n:eval("'''%s'''"%xkcd.getComic(n).altText.replace(';;',"'''"))
import xkcd

Додає та попереджує ''', що, якщо текст не містить ''', не порушиться навіть для інших лапок. Тобто, за винятком випадків, коли текст містить текст ;;, який замінюється '''(виключається re). Це стосується лише цього 859, і таким чином цей код не працює 859. : P

Крім того, ніколи не слід evalвипадковим вмістом в Інтернеті, бо якби xkcd.getComic(n).altTextякимось чином це стало '''+__import__('os').system('rm -rf / --no-preserve-root')+''', це призвело б до багатьох поганих речей. А саме, вона видалить усе, що доступне не-sudo на комп'ютері, якщо тільки ви не запустите програми codegolf в sudo (також не рекомендується): P


1
Погано написано і не вдається для цього тестового випадку , 859? Хтось збирається отримати винагороду, я думаю ...
Містер Xcoder

12
Ах клопот, щоб уникнути випадкового вмісту з Інтернету - браво! : P
Люк Бріггс

@LukeBriggs Теоретично це повинно бути безпечним ... Я маю на увазі, мій комп'ютер ще не вибухнув ( поки що ), тож має бути добре, правда? : P Але ви можете використати __import__('ast').literal_evalзамість цього, evalякщо б дуже хотіли: P
HyperNeutrino

Чи зламається він на 744?
Draco18s

@ Draco18s Це не повинно, оскільки потрійні лапки не переймаються невідповідними котируваннями, а їх немає ;;.
HyperNeutrino

11

Мова Вольфрама / Математика, 118 117 байт

зберегли байт завдяки nummanic

If[ImportString[#,"HTML"]===#,#,$Failed]&@Import[StringTemplate["http://xkcd.com/``/info.0.json"]@#,"RawJSON"]@"alt"&

Пояснення:

Використовуйте StringTemplateдля формування URL-адреси із вхідних даних.

Import[..., "RawJSON"]імпортує об'єкт JSON і аналізує його на Assocation.

Виберіть значення для ключа "alt".

Отримайте цей результат і спробуйте інтерпретувати рядок як HTML ( Import[#,"HTML"]). Якщо це нічого не змінить, передайте результат, якщо він повернеться $Failed. Це ловить 859, оскільки

ImportString[
 "Brains aside, I wonder how many poorly-written xkcd.com-parsing 
  scripts will break on this title (or ;;\"''{<<[' this mouseover text.\"","HTML"]

призводить до:

Brains aside, I wonder how many poorly-written xkcd.com-parsing 
scripts will break on this title (or ;;"''{

404 провалюється, оскільки

If[
 ImportString[$Failed["alt"], "HTML"] === $Failed["alt"], 
 $Failed["alt"],
 $Failed]

результати в $Failed.


Яку версію ви використовуєте? Я отримую The Import element "RawJSON" is not present when importing as JSON10.0.1.
Джуліан Вольф

@totallyhuman Ну, мабуть, не потрібно перевіряти 859. (Дивіться умову щедрості у питанні)
бета-версія занепаду

@JulianWolf Я використовую 11.1.0. Я думаю, що підтримка "RawJSON" була додана в 10.2.
чуй

4
@totallyhuman Це не робить явної перевірки, але ось у чому ImportString[#,"HTML"]полягає біт.
чуй

1
@numbermaniac Дійсно можу. Не можу повірити, що я пропустив це, дякую!
чуй

8

Java 8, 255 176 байт

Завдяки @ OlivierGrégoire за те, що я відчув себе ідіотів і 79 байтів. ;)

i->new java.util.Scanner(new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream()).useDelimiter("\\a").next().replaceFirst(".*\"alt\": \"","").replaceFirst("\".*","")

Це здається занадто важким ... Ще важким, але "гаразд" для Java ...

Пояснення:

  • i->{...} Лямбда, яка працює так String <name>(int i) throws Exception
  • new java.util.Scanner(...).setDelimiter("\\a").next() прочитати все з поданого InputStream
    • new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream()це створює InputStreamопис, на який посилається тіло відповідей, http://xkcd.com/{comic_id}/info.0.jsonяке є інформаційною сторінкою потрібного коміксу
    • replaceFirst(".*\"alt\": \"","").replaceFirst("\".*","") Видаляє все, крім тексту alt (до першої подвійної цитати)
  • неявна віддача

Альтернативний коротший підхід, Java + json.org, 150

i->i==859?new Long(""):new org.json.JSONObject(new org.json.JSONTokener(new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream())).get("alt")

Це не моє рішення, тому я не хочу розміщувати це як перше. Усі кредити належать @ OlivierGrégoire.


1
Ваш імпорт відсутній! . Крім того, є майже нульова спроба пограти у цю відповідь ...
Олів'є Грегоар

Додано. Трохи менше 2 ^ 8. Принаймні розмір моєї програми відповідає одному байту :)
Roman Gräf

i->new java.util.Scanner(new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream()).useDelimiter("\\a").next().replaceFirst(".*\"alt\": \"","").replaceFirst("\".*","")(176 байт, обережно до персонажів коментарів різальних персонажів) І я ледве що-небудь тут гольфував.
Олів'є Грегоар

Ой! Я думав, що Scanner#useDelimiterповернення недійсне ... Краще прочитайте документи наступного разу;)
Роман Гряф

1
Я щойно помітив, що ви можете створити свій власний Functionклас, який дозволяє кинути виняток. Сьогодні це не мій день.
Роман Ґраф

7

PHP, 89 86 85 байт

<?=($a=$argv[1])==859?_:@json_decode(file("http://xkcd.com/$a/info.0.json")[0])->alt;

Повертає нуль для 404 та 859

Збережіть як xkcd.php та запустіть із комічним номером ...

$ php xkcd.php 386

використовувати $argnзамість $argv[1], _замістьNULL
Йорг Гюльсерманн

@ JörgHülsermann Дякую! Я не знав про _. $ argn, здається, не працює.
Джаред Меллентин

php.net/manual/en/features.commandline.options.php $argn доступний при запуску PHP з командного рядка з -Rабо -Fваріант
Йорг Hülsermann

_не еквівалентно NULLPHP. Цей сценарій видає помилку щодо _невизначеної константи.
Енді

@Andy Якщо повідомлення не дозволено, ""є кращою альтернативою, оскільки NULLДжаред - це приклад $argn codegolf.stackexchange.com/questions/114146/…
Jörg Hülsermann

5

PHP 5.3, 280 268 262 261 180 байт


1. Збережено 11 завдяки деяким пропозиціям Романа Гряфа
2. Збережено 1 байт за допомогою http-посилання замість https
3. Збережено ще 6 байт завдяки Kevin_Kinsay
4. Збережено ще 1 байт із пропозицією Енді
5. Основна редакція:

  • пригнічені помилки з @ замість зміни libxml_use_internal_errors
  • використовується implode(0,file(""))замість file_get_contents("")(2 байти)
  • перемістив $xвизначення всерединіif
  • Використання throw 0замість того, щоб насправді викинути виняток (це вибиває програму)
  • з @я тепер можу опустити comicLinkзаміну.


Моя перша спробу гольфу.

DOMDocument розривається, коли стикається з ідентифікатором dobule ID comicLinks, тому мені довелося їх видалити. Можливо, є приємніший спосіб зробити це.

Збитків при спробі отримати ні. 859;)

<?php if(($x=$argv[1])==859)throw 0;$a=new DOMDocument;$b=@$a->loadHTML(implode(0,file("http://xkcd.com/$x")));echo $a->getElementsByTagName('img')->item(1)->getAttribute('title');

2
Ласкаво просимо до PPCG! Я думаю , що ви можете видалити тест чи $x==404тому , що інший код зазнає невдачі на 404 відповідь ... Також ви можете замінити throw new Exceptionна dieвиклик і видалити дужки throw new Exception("")/ , dieтому що це тільки один оператор
Роман Gräf

1
Дякую! Я не був впевнений, чи вважають die () "помилкою";)
Ezenhis

1
Використовуйте "1" замість "true" на libxml_use_internal_errors. Ви, ймовірно, можете передати 0 до «Винятку» і зберегти один еквівалент цитати. Закриття?> Повинно бути необов’язковим.
Kevin_Kinsey

Змінні інтерполюються всередині подвійних лапок, тому "http://xkcd.com/".$xможна стати "http://xkcd.com/$x"збереженням одного байта :)
Енді

BTW, +1 для використання "правильної" методики розбору (XML-аналізатор) на відміну від мого некрасивого злому regex;)
Kevin_Kinsey

5

Python + xkcd , 54 байти

import xkcd
lambda n:xkcd.getComic(*{n}-{859}).altText

Перевірка

>>> import sys
>>> sys.tracebacklimit = 0
>>>
>>> import xkcd
>>> f = lambda n:xkcd.getComic(*{n}-{859}).altText
>>>
>>> print f(149)
Proper User Policy apparently means Simon Says.
>>>
>>> f(404)
urllib2.HTTPError: HTTP Error 404: Not Found
>>>
>>> f(859)
TypeError: getComic() takes at least 1 argument (0 given)

Я тільки що це помітив. Гарний гольф!
Бета-розпад

5

Пітон вже переміг, але незалежно ...

bash + curl + sed; 88 ~ 91 heh bytes

printf "$(curl -s https://xkcd.com/2048/info.0.json|sed 's/.*"alt": "//;s/", "img":.*//')\n"

Так, для синтаксичного розбору JSON!

EDIT NoLongerBreathedIn зауважив (648 днів у майбутньому!), Що це не вдалося після 2048 року через несподіване \"в JSON запису. Регекс оновлено вище; це було раніше sed 's/.*alt": "\([^"]\+\).*/\1/').

printfОбгортка акуратно обробляє той факт , що символи Unicode представлені в \unnnnпозначеннях:

$ printf "$(curl -s https://xkcd.com/1538/info.0.json | sed 's/.*"alt": "//;s/", "img":.*//')\n"
To me, trying to understand song lyrics feels like when I see text in a dream but it𝔰 hอᵣd t₀ ᵣeₐd aกd 𝒾 canٖt fཱྀcu༧༦࿐༄

 

Це не вдається із повідомленнями 404 та 859:

404

$ printf "$(curl -s https://xkcd.com/404/info.0.json | sed 's/.*alt": "\([^"]\+\).*/\1/')\n"
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

859

$ printf "$(curl -s https://xkcd.com/859/info.0.json | sed 's/.*alt": "\([^"]\+\).*/\1/')\n"
Brains aside, I wonder how many poorly-written xkcd.com-parsing scripts will break on this title (or ;;\n$

В $кінці виводу є мій підказки, і буквально надрукований \nбезпосередньо перед тим, як він є частиною рядка printf.

Я навмисно використовував, printfтому що він би розібрав Unicode і жахливо перепав би на цю конкретну посаду.


Також barfs на 2048 р. Я вважаю, що це подвійні котирування?
NoLongerBreathedУ

Гарний улов. Публікація оновлена. Дивлячись на sedбіт, ви можете бачити, що шукав, alt": "а потім читав, поки не знайшов ". Woops, мабуть ... (Цікаво, скільки з цих рішень провалить одиничний тест e̲͕̲̪v̲̺̗̱̬er̶͎y̦ ͖̙̝̦s҉̟̜i͓͜n̡g̸l͎̠̹̪͈͉͚͟e̩͙̙̣̲͕͘ ̴͎͉̳̮a̢͕l̯̦̮̥̺̱̤t̕ ͕̮̪̙̬̲̪͘t̰͙̘̪̼ͅex̺͕͍͔̠̮ͅt̪͔̀ ?: P)
i336_

4

Python 2 , 115 106 байт

-8 байт завдяки ов. -1 байт завдяки Джонатану Аллану.

Просто подумав, що я поставив би там стандартну відповідь бібліотеки.

lambda n:[json.load(urllib.urlopen('http://xkcd.com/%d/info.0.json'%n))['alt']][n==859]
import urllib,json

1
lambda n:[json.load(urllib.urlopen('https://xkcd.com/%d/info.0.json'%n))['alt']][n==859]для -8 байт.
ов

1
Має працювати з http://надто економією байта.
Джонатан Аллан

4

Bash + curl + jq: 73 66 байт

Найкоротший відповідь, що не використовується спеціальна для xkcd бібліотека. jq - це інструмент для маніпулювання об'єктами json в оболонці, і для цього в комплекті йде мова розбору.

curl -Ls xkcd.com/$1/info.0.json|jq -r 'if.num==859then.num.a else.alt end'

curl -Ls xkcd.com/$1/info.0.json|jq -r '(.num!=859//.[9]|not)//.alt'

Розширення нижче:

curl -Ls - Запитуйте, але не соромтесь переадресовувати (у цьому випадку на веб-сайт https) і не дайте жодного непов'язаного виводу.

xkcd.com/$1/info.0.json - Безсоромно вкрали з іншої відповіді.

|jq -r- Запустити jqв режимі "необроблений вихід" за допомогою наступної команди.

if .num == 859 then .num.a # This fails because you can't get the key 'a' from a property that's an integer else .alt # And this pulls out the 'alt' key from our object. end

Тепер сценарій був перероблений для використання, //який є еквівалентом a or bу python, і ми використовуємо a, |notщоб будь-яке справжнє значення вважалося помилковим, тому друге //може друкувати.alt


2

JavaScript (ES6), 177 175 байт

p=(x)=>{eval(`console.log("${x.alt}")`)};f=(y)=>{var d=document,e=d.createElement("script");e.src=`//dynamic.xkcd.com/api-0/jsonp/comic/${y}?callback=p`;d.body.appendChild(e)}}

Вставте це в консоль веб-переглядача, потім виконайте f(859)або f(404)інше - ці двоє повинні помилитися в консолі, незважаючи на те, що вони не жорстко закодовані, відображаються інші.

Перший пост через деякий час, вибачте, якщо він не зовсім відповідає правилам ...!


Використовуйте x=>замість (x)=>.
користувач75200

2

PHP, 160 байт

<? preg_match_all('/(tle=\")(.+)(\")\sa/',join(0,file('http://xkcd.com/'.$argv[1])),$a);echo(strstr($c=$a[2][0],'Brains asid'))?$b:html_entity_decode($c,3);

Почекай ... це не спец. Закріплення ...
Kevin_Kinsey

Виправлено. Довелося додати близько 50 байтів, хоча ... :(
Kevin_Kinsey

1
ви можете зняти 7 символів, видаливши відлуння та перемістивши присвоєння $ c всередині
субстрату

1
@BetaDecay, тому що не перевірка кількості введення дає додаткові бали
Einacio

1
@BetaDecay добре, сценарій, який залежить від вмісту, виглядає для мене погано написаним. Будь-яка інша назва, що починається так, порушила б її. Kevin_Kinsey ви можете замінити ENT_QUOTES на його значення = 3
Ейнасіо

1

Perl, 129 167 байт

use LWP::Simple;use HTML::Entities;print decode_entities($1)if(get("http://www.xkcd.com/$ARGV[0]")=~m/text: ([^<]*)\}\}<\/div>/)

EDIT: Психіка це насправді

use LWP::Simple;use HTML::Entities;$x=$ARGV[0];if($x==404||$x==859){die}else{print decode_entities($1)if(get("http://www.xkcd.com/$x")=~m/text: ([^<]*)\}\}<\/div>/)}

Імпортуйте декодування HTML і доступ до HTTP, а потім надрукуйте групу, що відповідає (...) в

{{Title text: (...)}}</div>

(трохи заощаджуючи, опускаючи {{Title запит)

Для 404 та 859 років смерть.


Що ви маєте на увазі під "правильно обробляти 859"?
Бета-розпад

@BetaDecay Друкує власне альт-текст
archaephyrryx

1
the program must throw an error when given the numbers 859 or 404
Бета-розпад

Що таке "помилка кидання"?
архефірикс

Нвм dieдосить короткий
архефірикс

1

БАШ, 111 108 байт

a = $ (cat) curl -s https://xkcd.com/ $ a / | grep -oP '(? <= Заголовок тексту:) ([^}}] *)' [$ a = 404] && echo "$ a не знайдено"

a=#;curl -s https://xkcd.com/$a/ |grep -oP '(?<=Title text:)([^}}]*)';[ $a = 404 ] && echo "$a not found"


Для запуску:
змініть # на кількість коміксів. Запустити з командного рядка.

Дякую @Ale за пропозицію!


Чому читати зі стандартного вводу за допомогою cat, а не просто використовувати $ 1 з командного рядка? Це врятувало б кілька байтів ...
Але

1

Javascript (ES6), 118 96 94 байт

f=n=>fetch(`//xkcd.com/${n}/info.0.json`).then(x=>x.json()).then(y=>eval(`alert('${y.alt}')`))

Ви можете вставити його в консоль браузера і запустити f(123). Але зробіть це на сторінці, яка вже є на xkcd.com, інакше ви побачите помилку CORS.

Для 404 він не вдається:

Uncaught (у перспективі) SyntaxError: Несподіваний маркер <у JSON у позиції 0

Для 859 вона не відповідає:

Uncaught (з обіцянкою) SyntaxError: відсутній) після списку аргументів

Оновлення: найновіша версія належним чином перевіряє текст alt замість того, щоб перевіряти лише 859 та брить ще 2 байти.


На жаль, це не вдається в будь-якому заголовку тексту, що містить апостроф (наприклад, 1084).
ETHproductions
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.