xkcdを表示する


36

xkcdはみんなのお気に入りのウェブコミックであり、あなたは私たち全員にもう少しユーモアをもたらすプログラムを書くことになります。
この課題の目的は、入力として数値を受け取り、そのxkcdとそのタイトルテキスト(マウスオーバーテキスト)を表示するプログラムを作成することです。

入力

プログラムは、入力として正の整数(有効なコミックが存在する必要はありません)を受け取り、そのxkcdを表示します。たとえば、1500の入力は、xkcd.com / 1500でコミック「Upside-Down Map」を表示します。そして、タイトルテキストをコンソールに印刷するか、画像とともに表示します。

Due to their proximity across the channel, there's long been tension between North Korea and the United Kingdom of Great Britain and Southern Ireland. Due to their proximity across the channel, there's long been tension between North Korea and the United Kingdom of Great Britain and Southern Ireland.

テストケース2、n = 859の場合:

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

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

また、プログラムは入力なしで機能し、xkcd.comで見つかった最新のxkcdに対して同じタスクを実行できる必要があります。また、新しいものが起動しても常に最新のものを表示する必要があります。

xkcd.comから画像を直接取得する必要はありません。最新であり、この課題が発生する前にすでに存在していた限り、別のデータベースを使用できます。URL短縮、つまり、他の場所にリダイレクトする以外の目的のないURLは許可されません。

ブラウザなど、選択した方法で画像を表示できます。ただし、iframeなどで別のページの一部を直接表示することはできません。明確化:新しいページを作成する必要があるブラウザを使用する場合、既存のWebページを開くことはできません。また、実際に画像を表示する必要があります-画像ファイルの出力は許可されていません。

特定のコミックの画像がない場合(たとえば、インタラクティブであるか、プログラムがリリースされたコミックの数よりも大きい数を渡された場合)を、例外をスローするなどの合理的な方法で処理できます。 、または少なくとも1文字の文字列を印刷します。ただし、その入力用の画像がないことを何らかの形でユーザーに示している場合に限ります。

画像を表示してタイトルテキストを出力するか、無効なコミックに対してエラーメッセージを出力することしかできません。他の出力は許可されません。

これは挑戦なので、最少バイトが勝ちます。


1
@LukeFarritor画像を表示してタイトルテキストを出力するか、無効なコミックについて何らかのエラーメッセージを出力することしかできません。
パベル

9
サンプルサイズがimport antigravityPythonで1の場合;)
ウェインワーナー

15
面白い事実n=404 xkcd.com/404は404ページです。
魔法のタコUr

11
xkcd is everyone's favorite webcomic [引用が必要 ]
Sanchises

11
テストケース:859
betseg

回答:


13

Perl + curl + feh、86 84 75バイト

`curl xkcd.com/$_/`=~/<img src="(.*)" title="(.*?)"/;$_=$2;`feh "http:$1"`

-pスイッチが必要です。私はこれをバイト数で説明しました。


@Mattそれは私が試したすべての漫画で働いた。alt-textを含む画像のみに一致します。
spaghetto

src属性を引用符で囲む必要はありません。
コナーオブライエン

私はあなたが?最初のマッチグループで必要とは思わない。の代わりに-pand $_=$2を使用できますprint$2が、タイトルテキストはfehが閉じられた後にのみ印刷されます。それが有効かどうかわかりません。
m-chrzan

@ m-chrzanうん、嫌いな量指定子をそこに落とせるようだ。ありがとう。使用することを考えまし-pたが、OPがそれについてどのように感じるかはわかりませんでした。
spaghetto

@ ConorO'Brien残念ながら、ランドールは優れたHTMLコーディングプラクティスを順守しています...そして引用符をキャプチャすることは、Perlでのバックティックの動作方法のために引数を引用しません。
spaghetto

9

PowerShellのV3 + 110 99 107 103のバイト

iwr($x=((iwr "xkcd.com/$args").images|?{$_.title})).src.Trim("/") -outf x.jpg;if($x){ii x.jpg;$x.title}

インライン割り当てを使用してバイトを節約するために協力してくれたTimmyに感謝します。

引数が渡されない場合、$argsnullになり、現在のコミックが取得されます。代替テキストと一致する画像を、スクリプトの現在実行中のディレクトリ内のファイルにダウンロードします。次に、jpgのデフォルトビューアーで表示します。代替テキストはコンソールに表示されます。iwrはのエイリアスですInvoke-WebRequest

渡された数(またはその問題の無効な入力)が一致しない場合、プロセスは少なくとも404エラーで失敗します。

iwr(                                  # Request the comic image from XKCD
  $x=((iwr "xkcd.com/$args").images|  # Primary search to locate either the current image
                                      # or one matching an argument passed
     ?{$_.title}))                    # Find the image with alt text
        .src.Trim("/")                # Using the images associated link and strip the leading slashes
  -outf x.jpg                         # Output the image to the directory local to where the script was run
if($x){                               # Test if the image acquisition was successful
    ii x.jpg                          # Open the picture in with the default jpg viewer
    $x.title                          # Display alt text to console
}                                     # I'm a closing bracket.

このサブについてのコメント権限のみを取得しました。非常によく似た回答を
ご覧ください-colsw

@ConnorLSWあなたの答えの素晴らしいアプローチ。次回の検討事項。
マット

8

AutoIt、440バイト

はい、長いですが、安定しています。

#include<IE.au3>
#include<GDIPlus.au3>
Func _($0='')
_GDIPlus_Startup()
$1=_IECreate('xkcd.com/'&$0)
For $3 In $1.document.images
ExitLoop $3.title<>''
Next
$4=_GDIPlus_BitmapCreateFromMemory(InetRead($3.src),1)
$6=_GDIPlus_ImageGetDimension(_GDIPlus_BitmapCreateFromHBITMAP($4))
GUICreate(ToolTip($3.title),$6[0],$6[1])
GUICtrlSendMsg(GUICtrlCreatePic('',0,0,$6[0],$6[1]),370,0,$4)
_IEQuit($1)
GUISetState()
Do
Until GUIGetMsg()=-3
EndFunc

まず、これはRegExを使用してサイトをスクレイピングするのではなく(すべてのコミックでこれをテストする時間がありません)、代わりにInternet Explorer APIを使用してDOMのimgタグを繰り返し、タイトルテキストのあるものを見つけます。

バイナリストリームは画像URLから読み取られ、GDIPlusを使用してビットマップにレンダリングされます。これは、Webサイトとほぼ同じように動作するように、実際のツールチップを使用して、自動サイズ調整された素敵なGUIに表示されます。

テストケース(_(859))は次のとおりです。


4
ブラケットを画像に追加した方が良いでしょう。
マット

うわー、UbuntuのWineでAutoItを実行できることがわかりました。これで、IEで作業する必要があります。
考え直し

2
@ElPedro最新のCPUを使用している場合は、wineの代わりにqemu KVMとseamlessRDP(基本的にLinuxのDIYパラレル)を使用します。これにより、WindowsアプリがLinuxデスクトップにシームレスに統合され、100%の互換性とGPUパススルーが実現します。ただのヒント。
mınxomaτ

ありがとう@mınxomaτ。私はそれをやってみることができます。私は1日中Windowsで仕事をしているので、仕事以外ではLinux(さまざまなフレーバー)を使用することを好みますが、私はいつも実験に興味があります:)
エルペドロ

7

Powershell、93バイト

ローカル画像ビューアを使用する93バイト版。

$n=(iwr xkcd.com/$args).images|?{$_.title};$n.title;iwr ("http:"+$n.src) -OutF x.jpg;ii x.*

不要な二重引用符を削除して2バイトを節約し、次に-の("http:"+$n.src)代わりに"https://"+$n.src.trim("/")- を使用して別のロットを削除しました。これは、imgsrcが//既に含まれており、xkcdがhttpsを必要としないためです。

$n=(iwr xkcd.com/$args).images|?{$_.title};$n.title;saps ("http:"+$n.src)

$n=(iwr "xkcd.com/$args").images|?{$_.title};$n.title;saps ("https://"+$n.src.trim("/"))

Matts powershell answerと非常によく似ています(おそらくコメントですが、評判は低いはずです)

代わりに、これにより、デフォルトのブラウザで新しいタブ/ウィンドウが開き、その他のことも行われ、いくつかのバイトが節約されます。

iwr はのエイリアスです Invoke-WebRequest

sapsは、Start-Processデフォルトのコンテキストで「it」を開くエイリアスです。


既存のWebページを開くことに関するルールの端をすくい上げます。これは、既存の.jpg(または何でも)でブラウザーを直接起動するだけですが、いい答えです。
AdmBorkBork

@TimmyDはここで誤解している可能性があります-xkcd Webページ自体を使用できると仮定しました- デフォルトのローカルで開きたい場合は、最後に `-OutF x.jpg; ii x。*`に変更sapsiwrて追加することができます画像ビューア。
colsw

1
OPは、既存のWebページを開くことを許可しないことを指定しました。私が考える93バイト版はけれども結構です
spaghetto

私は、これはあなたが働く数与えれば、常に同じように機能するために起こっているとは思いませんその後、ない番号を。前回の実行から存在していたイメージを開きます。
マット

93バイトバージョンを受け入れますが、短いバージョンはパズルの条件に違反します。
パベル

4

R、358 328 310 298バイト

f=function(x){H="http:";p=paste0;library(XML);a=xpathSApply(htmlParse(p(H,'//xkcd.com/',x)),'//div/img',xmlAttrs)[[1]];download.file(p(H,a[1]),'a');I=`if`(grepl('png',a[1]),png::readPNG,jpeg::readJPEG)('a');d=dim(I)/100;quartz(,d[2],d[1]);par(mar=rep(0,4));frame();rasterImage(I,0,0,1,1);cat(a[2])}

新しい行とコメント:

f=function(x){
H="http:"
p=paste0
library(XML) #Needed for xpathSApply, htmlParse and xmlAttrs
# The following line find the first img element and extract its attributes
a=xpathSApply(htmlParse(p(H,'//xkcd.com/',x)),'//div/img',xmlAttrs)[[1]]
download.file(p(H,a[1]),'a') #Download to a file called 'a'
I=`if`(grepl('png',a[1]),png::readPNG,jpeg::readJPEG)('a') #Check if png or jpeg and load the file accordingly
d=dim(I)/100 #convert dimension from pixel to inches (100 ppi).
quartz(,d[2],d[1]) #open a window of the correct dimension
par(mar=rep(0,4)) #Get rid of margins
frame() #Create empty plot
rasterImage(I,0,0,1,1) #Add png/jpeg to the plot
cat(a[2]) #Print title text to stdout
}

テストケースのスクリーンショット:

x = 1500の場合: x = 1500(png)

xが空の場合:
x = ''の場合

画像がJPEGの場合:
x = 10(jpeg)の場合

x = 859:
x = 859


画像を正しい寸法で表示する必要があるのだろうか。この挑戦で遊んでいたとき、私はただやっplot.new();rasterImage(...)ただけです。
ビリーウォブ

@Billywobさて、プロットのデフォルトのサイズは7x7インチなので、完全に歪んでしまいます。それはOPが明示的に歪められないように画像を要求していなかったことは事実だが、私はこのようにそれを好む:)私はしかし、の退治検討していますxaxsし、yaxsまだ比例になり、結果として。
プランナパス


2

Python 2.7、309 299 295 274バイト

完全なプログラム。間違いなくもっとゴルフに適していますが、xkcdコミックを長い間読んでいたので、これを渡すことはできませんでした(これが将来xxcdを簡単に閲覧するのに役立つかどうかはわかりません)。

入力が渡されない場合、現在のコミックを取得します。有効なコミック番号が入力として渡されると、そのコミックが取得されます。無効な入力(有効な範囲のコミックではない)が渡されると、エラーがスローされます。

バイト数を減らす方法についての提案は大歓迎です!時間があれば、再訪(および説明を追加)します。

@Dopappのおかげで-10バイト

@Shebangのおかげで-21バイト

import urllib as u,re
from PIL import Image
h='http://';x='xkcd.com/'
o=u.URLopener()
t=u.urlopen(h+x+raw_input()).read()
c=sum([re.findall(r,t)for r in[h+'imgs.'+x+'c.*s/.*\.\w{1,3}','\.\w{1,3}" t.*e="(.*)" a']],[])
Image.open(o.retrieve(c[0],'1.png')[0]).show();print c[1]

1
あなたは変えることができるtry:...except:...するtry:n=...except:n=''、あなたの総バイト数10を節約
ダニエル

1
なぜあなたはtry声明さえ持っていますか?プログラムの仕様では、常に正の整数を取得すると書かれています。
ケード

@Shebangは、入力がない場合も最新のコミックを返す必要があります。入力エラーの例外を把握せずにこのケースを管理することはできませんでした。
イオアンズ

1
@Joannesなぜ使用しないのraw_input()ですか?デフォルトでは、ユーザが押すことができます[Enter]し、nとにかく空の文字列が含まれています。そのtry-exceptブロックを削除しt=u.urlopen(h+x+n).read() -> t=u.urlopen(h+x+raw_input()).read()て、274バイトにした場合。
ケード

xkcdイメージURLはを使用するため、これは機能しなくなりましたhttps。ただし、投稿時に機能していたため、まだ有効です。動作させるには、行3をh='https://'+1バイトで開始するように変更します。
メゴ

2

PHP、42バイト

<?=@file('http://xkcd.com/'.$_GET[i])[59];

ファイルに保存し、選択したWebサーバーで起動します


1
PPCGへようこそ!PHPはわかりませんが、画像のタイトルテキストを取得しているコードの一部はないようです。
パベル

1

JavaScript + HTML、124 + 18 = 142バイト

i=>fetch(`//crossorigin.me/http://xkcd.com/${i||""}/info.0.json`).then(r=>r.json()).then(d=>(A.innerHTML=d.alt,B.src=d.img))
<img id=B><p id=A>

ここでのKaiidoの回答によるクロスオリジンソリューション。

//crossorigin.me/xkcd.comへの接続に必要なプロキシを差し引くことができる場合、17バイト()を節約できます(これに関するメタ投稿)。

テストスニペット

f=
i=>fetch(`//crossorigin.me/http://xkcd.com/${i||""}/info.0.json`).then(r=>r.json()).then(d=>(A.innerHTML=d.alt,B.src=d.img))
<style>img{width:50%}</style><input id=I> <button onclick="f(I.value)">Run</button><br>
<img id=B><p id=A>


1

Python 3 +リクエスト+ PIL、192 186バイト

from requests import*
import PIL.Image as f
from io import*
r=get("https://xkcd.com/%s/info.0.json"%input()).json()
f.open(BytesIO(get(r["img"],stream=1).content)).show()
print(r["alt"])

コミックを含むイメージビューアー(実行されているシステムのデフォルト)を開き、タイトルテキストをコンソールに投稿します。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.