障害のある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は、番号をチェックする代わりに記述が不十分であるため失敗します。

他の代替テキスト(744など)で、括弧、引用符などが一致しない場合、プログラムが中断する可能性があります。

勝ち

バイト単位の最短コードが優先されます。


2
スクリプトを破るaltテキストを含む他の漫画(744を参照)があるので、プログラムがそれらを壊しても大丈夫ですか?
完全に人間

8
@totallyhumanそれに少しNSFW警告を追加する必要があります
。P– HyperNeutrino

11
課題の矛盾:「859または404」以外の数字についてはエラーをスローしてはなりません。「および他の代替テキストで中断する可能性があります」。
アシェプラー

3
@aschepler後者は報奨金のみです
ベータ崩壊

4
@Kzqaiいい質問ですが、DDOSに関係するトラフィックの量と、xkcd.comがすでに持っているトラフィックの量を少し過小評価していると思います。ここでの回答から生成されるトラフィックが、これらのいずれかと比較して重要になるとは思わないでしょう。
trichoplax

回答:


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がさらに魅力的になりました!
ナット


6
偶然にも、pythonは確かにimport'ingをサポートしantigravityます。
さらに別のユーザー

39
Pythonはこの課題をMathematicaだけでしたか?
アークトゥルス

22

パイソン2 + リクエスト104の 102 95 94バイト

Erik the Outgolferのおかげで-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==859JSONデコーダがために失敗したので、404とにかく。
musicman523

7
... http://ここでも使用できると思います。
ジョナサンアラン

1
パラメータを使用して実際にどのように実行しますか?たとえば、名前のないラムダをどのように実行しますか?
-MrZander

1
@MrZander最初の行は、実行する変数に割り当てることができる匿名ラムダです。例えば、両方f = lambda n: n * 2; print f(2)または(lambda n: n * 2)(2)4印刷する
totallyhuman

18

Python 2 + xkcd、82バイト

不十分なスクリプト

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

Appendsおよびprependsは'''、テキストにが含まれていない限り、'''他の引用符であっても壊れません。これは、テキストが含まれている場合を除いて、ある;;に置き換えますされ、'''(排除します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トリプルクォートはクォートの不一致を気にしないので、そうすべきではありません;;
ハイパーニュートリノ

11

Wolfram言語 / Mathematica、118 117バイト

numbermanicのおかげで1バイト節約

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で追加されたと思います。
-chuy

4
@totallyhuman明示的なチェックは行いませんが、それがImportString[#,"HTML"]ビットです。
-chuy

1
@numbermaniac本当にできます。私がそれを見逃したとは信じられない、ありがとう!
-chuy

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("\".*","") 代替テキスト以外のすべてを削除します(最初の二重引用符まで)
  • 暗黙の戻り

別の短いアプローチ、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のすぐ下。少なくとも私のプログラムのサイズは1バイトに収まります:)
RomanGräf17年

i->new java.util.Scanner(new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream()).useDelimiter("\\a").next().replaceFirst(".*\"alt\": \"","").replaceFirst("\".*","")(176バイト、SOのコメントカッターキャラクターに注意してください)そして、私はここでほとんど何もゴルフしませんでした。
オリビエグレゴワール

ああ!Scanner#useDelimitervoidを返すと思った...次回ドキュメントを読むのが良い;)
ローマングレーフ

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に対してnullを返します

xkcd.phpとして保存し、コミック番号で実行します...

$ php xkcd.php 386

使用$argnの代わりに$argv[1]_代わりにNULL
イェルクHülsermann

@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/...
イェルクHülsermann

5

PHP 5.3、280の 268 262 261 180バイト


1. RomanGräfのいくつかの提案のおかげで11を保存
2. httpsの代わりにhttpリンクを使用して1バイトを
保存3. Kevin_Kinsayのおかげでさらに6バイトを
保存4. Andyの提案でさらに1バイトを保存
5.主要な改訂:

  • 変更する代わりに@でエラーを抑制 libxml_use_internal_errors
  • implode(0,file(""))代わりに使用file_get_contents("")(2バイト)
  • $x定義を内部に移動しましたif
  • throw 0実際に例外をスローする代わりに使用する(プログラムをクラッシュさせる)
  • @私は今、comicLink置換を省略することができます。


ゴルフを始めてみました。

dobule ID comicLinksに遭遇するとDOMDocumentが壊れるため、これらを削除する必要がありました。おそらくもっと良い方法があります。

取得しようとするとクラッシュします。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 Exceptiondieコールし、周りのブラケットを取り外しthrow new Exception("")/ dieそれはひとつの文のみであるので
ローマグラーフ

1
ありがとう!die()が「エラーを投げる」としてカウントされるかどうかは
わかりませんでした

1
libxml_use_internal_errorsで「true」の代わりに「1」を使用します。おそらく例外に0を渡し、同等の引用符を1つ保存できます。終了?>はオプションです。
-Kevin_Kinsey

変数は二重引用符内に補間されるため、1バイトの節約に"http://xkcd.com/".$xなり"http://xkcd.com/$x"ます:)
Andy

ところで、私のい正規表現ハックとは対照的に、「適切な」解析手法(XMLパーサー)を使用するための+1;)
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

Pythonのものはすでに勝ちましたが、関係なく...

bash + curl + sed; 88〜91 あわやバイト

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

正規表現JSON解析に賛成です!

EDIT NoLongerBreathedInは\"、そのエントリのJSON での予期しないために、ポスト2048でこれが失敗したことに気づきました(未来648日!)。正規表現は上記で更新されました。以前はそう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の文字列の一部である直前に。

printfUnicode 解析し、この特定の投稿でひどく落ちてしまうので、意図的に使用しました。


また、2048のバーフ。二重引用符のバーフだと思う?
NoLongerBreathed

ナイスキャッチ。投稿を更新しました。sedビットを見ると、それが探していてalt": "、が見つかるまで読んでいたことがわかります"。Woops、明らかに...(私はのユニットテスト失敗していましたどのように多くのこれらのソリューションのだろ あらゆる͖̙̝̦s҉̟̜i͓͜n̡g̸l͎̠̹̪͈͉͚͟e̩͙̙̣͕͘ALTテキスト:P?)
i336_

4

パイソン2115の 106バイト

ovsのおかげで-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バイトの場合。
ovs

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次のコマンドで「raw出力」モードで実行します。

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

現在、スクリプトはPythonに//相当するものa or bを使用する|notように作り直されており、aを使用して真の値を偽と見なすため、2番目//.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)など- 2は、コンソールにエラーすべきものを、ハードコーディングされていないにも関わらず、他の人が表示します。

しばらくして最初の投稿、ルールを完全に満たしていない場合は申し訳ありません...!


x=>代わりに使用します(x)=>
user75200

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文字を削除してエコーを削除し、substr内で$ c割り当てを移動できます
Einacio

1
@BetaDecay入力番号をチェックしないと余分なポイントが得られるため
Einacio

1
@BetaDecayよく、コンテンツに依存するスクリプトは私にはあまり書かれていません。そのように始まる他のタイトルはそれを壊します。Kevin_Kinsey ENT_QUOTESをvalue = 3で置き換えることができます
Einacio

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

編集:プシュケは実際に

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
ベータ崩壊

「エラーを投げる」とは何ですか?
アーケフィリクス

Nvm dieは十分に短い
-archaephyrryx

1

BASH、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!


コマンドラインから$ 1を使用する代わりにcatを使用して標準入力から読み取るのはなぜですか?それはいくつかのバイトを節約します
エール

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(promise)SyntaxError:予期しないトークン<JSONの位置0

859の場合、次のように失敗します。

引数リストの後にキャッチされない(約束)SyntaxError:missing)

更新:最新バージョンでは、859と2バイトのシェービングだけをチェックするのではなく、代替テキストを適切にチェックします。


悲しいことに、これはアポストロフィを含むタイトルテキスト(例:1084)では失敗します。
-ETHproductions
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.