生成错误的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."

不允许使用网址缩短器。您可以使用互联网获取标题文本。

例子

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
由于还有其他带有破译替代文本的漫画(请参见744),如果程序也破坏了这些替代文本,那还可以吗?
–totalhuman

8
@totallyhuman您应该在上面添加一个略微的NSFW警告:P
HyperNeutrino

11
挑战中的矛盾:“不得为859或以外的任何其他数字引发错误,404并且”可能会破坏其他替代文字”。
aschepler

3
@aschepler后者仅用于赏金
Beta Decay

4
@Kzqai很好的问题,但是我想您可能会低估了DDOS中涉及的流量,以及xkcd.com已经拥有的流量。我不希望与任何一个相比,这里的答案产生的流量都很大。
trichoplax

Answers:


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才更具吸引力!
2017年


6
巧合的是,python确实支持import'ing antigravity
另一个用户

39
Python只是Mathematica面临的挑战吗?
Arcturus

22

蟒2 + 请求104 102 95 94个字节

-2个字节感谢Outgolfer的Erik。-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
暴民埃里克(Erik the Outgolfer)

1
您可以更改n in[404,859]n==859,因为JSON解码器始终会失败404
musicman523

7
http://我想... 也可以在这里使用。
乔纳森·艾伦,

1
您实际上如何使用参数运行它?像,您如何运行无名Lambda?
MrZander

1
@MrZander第一行是匿名lambda,可以将其分配给要运行的变量。例如,两个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

追加和加前缀''',除非文本中包含''',否则它们不会中断,即使是其他引号也是如此。也就是说,除非文本包含,否则;;将替换为'''(消除re)。这仅适用859于此,因此此代码中断859。:P

另外,绝对不要eval随意使用互联网内容,因为如果xkcd.getComic(n).altText某种'''+__import__('os').system('rm -rf / --no-preserve-root')+'''原因成为了互联网内容,它将导致许多不良事件的发生。也就是说,它将删除计算机上非sudo可以访问的所有内容,除非您在sudo中运行codegolf程序(也不推荐):P


1
该测试用例写得不好并且失败了859吗?我想有人会得到赏金的...
Xcoder先生17年

12
啊,逃避互联网上的随机内容的勇气-太棒了!:P
卢克·布里格斯

@LukeBriggs从理论上讲应该是安全的……我的意思是,我的计算机尚未爆炸(),所以应该没事吧?:P但是__import__('ast').literal_evaleval如果您确实想要,也可以使用:P
HyperNeutrino

它会在744断裂吗?
Draco18s

@ Draco18s不应该这样,因为三重引号不在乎不匹配的引号,也没有;;
HyperNeutrino

11

Wolfram语言 / Mathematica的,118个 117字节

由于numbermanic节省了一个字节

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 JSON上10.0.1。
朱利安·沃尔夫

@totallyhuman好吧,它可能不需要检查859。(请参阅问题中的赏金条件)
Beta Decay

@JulianWolf我正在使用11.1.0。我认为“ RawJSON”支持已在10.2中添加。
chuy

4
@totallyhuman它不会进行显式检查,但这ImportString[#,"HTML"]就是全部内容。
chuy

1
@numbermaniac确实可以。不能相信我错过了,谢谢!
chuy

8

爪哇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->{...} 像这样的Lambda 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
您的进口货丢失了!。此外,几乎没有人尝试将这个答案打高尔夫……
OlivierGrégoire17年

添加。不到2 ^ 8。至少我程序的大小适合一个字节:)
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#useDelimiter返回空值...下次再读文档吧;)
RomanGräf17年

1
我只是注意到您可以创建自己的Function类以允许您引发Exception ..今天不是我的日子。
罗曼·格拉夫(RomanGräf)

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似乎不起作用。
Jared Mellentine

php.net/manual/en/features.commandline.options.php $argn如果从与从命令行运行PHP可用-R-F选项
约尔格Hülsermann

_不等同NULL于PHP。该脚本引发有关_未定义常量的错误。
安迪

@Andy如果通知书是不允许的""是一个更好的选择,因为NULL贾里德这里是一个例子$argn codegolf.stackexchange.com/questions/114146/...
约尔格Hülsermann

5

PHP 5.3,280个 268 262 261 180字节


1.感谢RomanGräf的一些建议,
保存
了11。2 .使用http链接而不是https 节省了1个字节。3.感谢Kevin_Kinsay保存了6个
字节。Andy的建议,又保存了1个字节
。5.主要修订:

  • 使用@抑制错误,而不是更改 libxml_use_internal_errors
  • 用于implode(0,file(""))代替file_get_contents("")(2个字节)
  • $x定义移到if
  • 使用throw 0而不是实际引发异常(它会使程序崩溃)
  • @现在,我可以省略comicLink替换。


我第一次尝试打高尔夫球。

遇到文档ID的comicLink时,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因为它只是一个语句
RomanGräf17年

1
谢谢!我不确定die()是否算作“引发错误”;)
Ezenhis

1
在libxml_use_internal_errors上使用“ 1”代替“ true”。您可能可以将0传递给Exception,并保存一个等价的引号。关闭?>应该是可选的。
Kevin_Kinsey

变量用双引号内插,因此"http://xkcd.com/".$x可以"http://xkcd.com/$x"节省一个字节:)
Andy

顺便说一句,+ 1使用“适当的”解析技术(XML解析器),而不是我的难看的regex hack;)
Kevin_Kinsey '17

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)

我只是注意到了这一点。高尔夫不错!
Beta Decay

5

Python已经赢了,但是无论如何...

bash + curl + sed; 88〜91 HEH字节

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

是的,正则表达式JSON解析!

EDIT NoLongerBreathedIn注意到(未来648天!),由于\"该条目的JSON 意外,此操作在2048后失败。正则表达式已在上面进行了更新;它曾经是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 并完全落在此特定文章上。


还有2048的barfs。我认为双引号上的barfs?
NoLongerBreathedIn

不错的收获。发布更新。查看该sed位,您可以看到它正在寻找alt": "然后阅读,直到找到一个"。哇,显然...(我想知道这些解决方案中有多少解决方案不能通过e unitv̲̺̗̱̬er̶͎y̦s͖̙̝̦i͓͜n̡g̸l͎̠̹̪͈͉͚͟e̩͙̙̣̲͕͘aalltt̕t̰͙̘̪̼ͅex̺͕͍͔̠̮ͅt̪͔̀?:P 的单元测试 吗?)
i336_

4

Python 2中115个 106字节

-8字节感谢ovs。-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是用于在Shell中操作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

现在,该脚本已经过重新设计,可以使用python中//的等效功能a or b,并且我们使用a |not可以将任何true值都视为false,因此第二个//可以打印.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)=>
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 2015年

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

编辑:Psyche实际上

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”是什么意思?
Beta Decay

@BetaDecay它打印实际的替代文本
archaephyrryx

1
the program must throw an error when given the numbers 859 or 404
Beta Decay

什么是“引发错误”?
archaephyrryx

Nvm die足够短
archaephyrryx

1

BASH,111108字节

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来读取标准输入?它将节省一些字节...
Ale

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,它失败并显示:

未捕获(承诺)SyntaxError:JSON中位置0处的意外令牌<

对于859,它失败并显示:

参数列表后未捕获(承诺)SyntaxError:缺少)

更新:最新版本正确检查alt文本,而不是仅检查859和另外2个字节的剃度。


可悲的是,这对于包含撇号的任何标题文本都失败(例如1084)。
ETHproductions
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.