Tampilkan xkcd

36

xkcd adalah webcomic favorit semua orang, dan Anda akan menulis sebuah program yang akan membawa sedikit lebih banyak humor kepada kita semua.
Tujuan Anda dalam tantangan ini adalah untuk menulis sebuah program yang akan mengambil angka sebagai input dan menampilkan xkcd dan teks-judulnya (teks mousover).

Memasukkan

Program Anda akan mengambil bilangan bulat positif sebagai input (tidak harus yang memiliki komik yang valid) dan menampilkan xkcd: misalnya, input 1500 harus menampilkan komik "Peta Terbalik" di xkcd.com/1500, dan kemudian cetak judul-teksnya ke konsol atau tampilkan dengan gambar.

Karena kedekatannya dengan saluran, ada ketegangan lama antara Korea Utara dan Kerajaan Inggris Raya dan Irlandia Selatan. 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.

Test case 2, untuk n = 859:

Selain otak, saya bertanya-tanya berapa banyak skrip parsing xkcd.com yang ditulis dengan buruk akan melanggar judul ini (atau ;; "'' {<< ['mouseover text ini."

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

Program Anda juga harus dapat berfungsi tanpa input apa pun, dan melakukan tugas yang sama untuk xkcd terbaru yang ditemukan di xkcd.com, dan itu harus selalu menampilkan yang terbaru bahkan ketika yang baru naik.

Anda tidak harus mendapatkan gambar secara langsung dari xkcd.com, Anda dapat menggunakan database lain selama ini up-to-date dan sudah ada sebelum tantangan ini naik. URL pendek, yaitu url tanpa tujuan selain mengarahkan ke tempat lain, tidak diperbolehkan.

Anda dapat menampilkan gambar dengan cara apa pun yang Anda pilih, termasuk di browser. Anda tidak boleh , bagaimanapun, secara langsung menampilkan bagian dari halaman lain dalam iframe atau yang serupa. CLARIFICATION: Anda tidak dapat membuka halaman web yang sudah ada sebelumnya, jika Anda ingin menggunakan browser Anda harus membuat halaman baru . Anda juga harus benar-benar menampilkan gambar - mengeluarkan file gambar tidak diperbolehkan.

Anda dapat menangani kasing yang tidak ada gambar untuk komik tertentu (mis. Interaktif atau program dilewati angka yang lebih besar dari jumlah komik yang telah dirilis) dengan cara yang Anda inginkan, termasuk melemparkan pengecualian , atau mencetak sekurang-kurangnya string karakter tunggal, selama entah bagaimana itu menandakan kepada pengguna bahwa tidak ada gambar untuk input itu.

Anda hanya dapat menampilkan gambar dan menampilkan judul-teksnya, atau menampilkan pesan kesalahan untuk komik yang tidak valid. Output lain tidak diizinkan.

Ini adalah tantangan , sehingga byte paling sedikit menang.

Pavel
sumber
1
@LukeFarritor Anda hanya dapat menampilkan gambar dan menampilkan teks judul atau menampilkan beberapa bentuk pesan kesalahan untuk komik yang tidak valid.
Pavel
9
Jika ukuran sampel Anda adalah 1, import antigravitydengan Python;)
Wayne Werner
15
Fakta lucu n=404 xkcd.com/404 adalah halaman 404.
Magic Octopus Mm
11
xkcd is everyone's favorite webcomic [Rujukan? ]
Sanchises
11
Test case: 859
betseg

Jawaban:

13

Perl + curl + feh, 86 84 75 byte

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

Membutuhkan -psakelar. Saya telah memperhitungkan ini dalam hitungan byte.

sebuah spaghetto
sumber
@ Matt Ini bekerja pada semua komik yang saya coba. Ini hanya cocok dengan gambar dengan alt-teks begitu.
spaghetto
Anda mungkin tidak memerlukan tanda kutip di sekitar atribut src.
Conor O'Brien
Saya tidak berpikir Anda membutuhkan ?di grup pertandingan pertama. Anda bisa menggunakan -pdan $_=$2bukannya print$2, tetapi kemudian teks judul dicetak hanya setelah feh ditutup. Tidak yakin apakah itu valid.
m-chrzan
@ m-chrzan Ya sepertinya saya bisa meletakkan quantifier enggan di sana, terima kasih. Saya berpikir untuk menggunakan -ptetapi tidak yakin bagaimana perasaan OP tentang hal itu.
spaghetto
@ ConorO'Brien Sayangnya Randall mengamati praktik pengkodean HTML yang baik ... dan menangkap tanda kutip tidak lantas mengutip argumen karena cara kerja backticks di Perl.
spaghetto
9

PowerShell v3 + 110 99 107 103 Bytes

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

Terima kasih kepada Timmy karena telah membantu menghemat beberapa byte dengan menggunakan penugasan sebaris.

Jika tidak ada argumen yang dilewatkan maka $argsadalah nol dan itu hanya akan mendapatkan komik saat ini. Unduh gambar, dengan mencocokkannya dengan teks alternatif, ke dalam file di direktori skrip yang sedang berjalan. Kemudian tampilkan dengan penampil default jpg's. Teks alt kemudian ditampilkan ke konsol. iwradalah alias untukInvoke-WebRequest

Jika nomor yang dilewati (atau input yang tidak valid untuk hal ini) tidak cocok dengan proses gagal dengan setidaknya 404 kesalahan.

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.
Mat
sumber
Baru saja mendapat hak komentar saya di sub ini sekarang, periksa jawaban
colsw
@ConnorLSW Pendekatan yang bagus dalam jawaban Anda. Hal-hal yang dipikirkan untuk waktu berikutnya.
Mat
8

Otomatis , 440 byte

Ya, panjang, tapi stabil.

#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

Pertama-tama, ini tidak menggunakan RegEx untuk mengikis situs (karena saya tidak punya waktu untuk menguji ini pada semua komik), melainkan menggunakan Internet Explorer API untuk beralih melalui imgtag DOM sampai menemukan satu dengan teks judul.

Aliran biner dibaca dari URL gambar dan dirender ke dalam bitmap menggunakan GDIPlus. Ini kemudian ditampilkan dalam GUI yang bagus dan berukuran otomatis dengan tooltip yang sebenarnya untuk membuatnya berperilaku hampir persis seperti situs web.

Berikut ini adalah test case ( _(859)):

)

mınxomaτ
sumber
4
Akan lebih baik jika Anda menambahkan braket kembali ke dalam gambar.
Mat
Wow, baru tahu kalau saya bisa menjalankan AutoIt di bawah Wine di Ubuntu. Sekarang yang perlu saya lakukan adalah membuat IE bekerja di sana. Pikiran kedua ... +1 untuk jawabannya
ElPedro
2
@ ElPedro Jika Anda memiliki CPU modern, gunakan qemu KVM dan seamlessRDP (pada dasarnya merupakan paralel DIY untuk linux) daripada anggur. Ini mengintegrasikan aplikasi Windows dengan mulus ke desktop linux dan memiliki kompatibilitas 100% + GPU passthrough. Hanya sebuah tip.
mınxomaτ
Terima kasih @ mınxomaτ. Saya mungkin mencobanya. Saya bekerja dengan Windows sepanjang hari, jadi saya lebih suka menggunakan Linux (berbagai rasa) dari pekerjaan tetapi saya selalu tertarik untuk bereksperimen :) Tip diterima dengan rasa terima kasih.
ElPedro
7

Powershell, 93 Bytes

Versi 93 Byte untuk menggunakan penampil gambar lokal.

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

Disimpan 2 byte dengan menghapus doublequote yang tidak perlu, lalu banyak lagi dengan menggunakan ("http:"+$n.src)alih-alih "https://"+$n.src.trim("/")- karena imgsrc //sudah ada di dalamnya, dan xkcd tidak memerlukan 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("/"))

sangat mirip dengan jawaban Matts PowerShell, (mungkin seharusnya komentar tetapi reputasi rendah)

Sebaliknya ini membuka tab / jendela baru di browser default, dan hal-hal lain, menghemat beberapa byte.

iwr adalah alias untuk Invoke-WebRequest

sapsadalah alias untuk Start-Processyang membuka 'itu' dalam konteks default.

colsw
sumber
Melewati batas aturan tentang membuka halaman web yang ada, karena ini secara langsung meluncurkan browser di .jpg yang sudah ada sebelumnya (atau apa pun), tetapi jawaban yang bagus.
AdmBorkBork
@TimmyD mungkin telah salah paham di sini kemudian - Saya berasumsi Anda dapat menggunakan halaman web xkcd itu sendiri - Anda hanya dapat mengubah sapske iwrdan append `x.jpg -OutF;. Ii x *` sampai akhir jika Anda ingin membuka di default lokal penampil gambar.
colsw
1
OP menetapkan bahwa Anda tidak diizinkan untuk membuka halaman web yang sudah ada sebelumnya. Versi 93 byte yang saya pikir baik-baik saja
spaghetto
Saya tidak berpikir ini akan selalu berfungsi sama jika Anda memberikan angka yang berfungsi maka angka yang tidak. Ini akan membuka gambar yang ada dari jalankan sebelumnya.
Mat
Saya menerima versi 93 byte, tetapi versi Anda yang lebih pendek melanggar kondisi puzzle.
Pavel
4

R, 358 328 310 298 byte

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])}

Dengan baris dan komentar baru:

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
}

Cuplikan layar kasus uji:

untuk x = 1500: untuk x = 1500 (png)

untuk x kosong:
untuk x = ''

kasus ketika gambar adalah jpeg:
untuk x = 10 (jpeg)

x = 859:
x = 859

plannapus
sumber
Saya ingin tahu apakah perlu untuk menampilkan gambar dalam dimensi yang benar. Ketika saya bermain-main dengan tantangan ini, saya hanya melakukannya plot.new();rasterImage(...).
Billywob
@ Billywob Yah itu akan sepenuhnya terdistorsi karena ukuran default untuk plot adalah 7x7 inci. Memang benar bahwa OP tidak secara eksplisit meminta gambar untuk tidak terdistorsi tetapi saya lebih suka dengan cara ini :) Namun saya mempertimbangkan menyingkirkan xaxsdan yaxskarena hasilnya masih akan proporsional.
plannapus
3

PHP, 95 byte

<?php echo str_replace("title=\"","/>",file_get_contents("https://xkcd.com/".$_GET["id"])); ?>

Simpan sebagai main.php, jalankan server

php -S localhost:8123

Buka http: // localhost: 8123 / main.php? Id = 1500

Евгений Новиков
sumber
2

Python 2.7, 309 299 295 274 byte

Program lengkap. Jelas lebih golf, tetapi setelah membaca komik xkcd begitu lama saya tidak bisa membiarkan ini berlalu (siapa yang tahu apakah ini akan membantu di masa depan untuk dengan mudah menelusuri xkcd).

Jika tidak ada input yang dilewati, dapatkan komik saat ini. Jika nomor komik yang valid diteruskan sebagai input maka dapatkan komik itu. Jika input yang tidak valid (bukan komik angka dalam rentang yang valid) dilewatkan, melempar kesalahan.

Ada saran tentang cara mengurangi jumlah byte. Akan mengunjungi kembali (dan menambahkan penjelasan) ketika saya memiliki lebih banyak waktu.

-10 byte berkat @Dopapp

-21 byte terima kasih kepada @Shebang

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]
Ioannes
sumber
1
Anda dapat mengubah try:...dan except:...ke try:n=...dan except:n='', menghemat total 10 byte
Daniel
1
Mengapa Anda bahkan punya trypernyataan? Spesifikasi program mengatakan Anda akan selalu mendapatkan bilangan bulat positif.
Kade
@ Shebang juga harus mengembalikan komik terbaru ketika tidak ada input. Saya tidak dapat mengelola kasus ini tanpa mengabaikan pengecualian kesalahan input.
Ioannes
1
@ Joannes Mengapa tidak digunakan raw_input()? Secara default, pengguna dapat menekan [Enter]dan nakan berisi string kosong. Jika Anda menghapus blok coba-kecuali dan apakah t=u.urlopen(h+x+n).read() -> t=u.urlopen(h+x+raw_input()).read()Anda mendapatkannya hingga 274 byte.
Kade
Ini tidak lagi berfungsi, karena URL gambar xkcd digunakan https. Namun, itu masih berlaku, karena berfungsi pada saat memposting. Untuk membuatnya berfungsi sekarang, ubah baris 3 untuk memulai dengan h='https://'+1 byte.
Mego
2

PHP, 42 byte

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

Simpan ke file dan jalankan di server web pilihan Anda

Jared Mellentine
sumber
1
Selamat datang di PPCG! Saya tidak tahu PHP, tetapi sepertinya tidak ada bagian dari kode Anda yang mengambil teks judul gambar?
Pavel
1

JavaScript + HTML, 124 + 18 = 142 byte

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>

Solusi lintas-asal berkat jawaban Kaiido di sini .

17 byte ( //crossorigin.me/) dapat disimpan jika proxy yang diperlukan untuk terhubung ke xkcd.com dapat dikurangi ( meta posting tentang ini ).

Cuplikan Tes

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>

Justin Mariner
sumber
1

Python 3 + Permintaan + PIL, 192 186 byte

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"])

Membuka penampil gambar (mana yang merupakan default pada sistem yang sedang dijalankannya) yang mengandung komik, dan memposting teks judul ke konsol.

Lirik
sumber
1

Bahasa Wolfram 45 byte (Mathematica)

Import["https://xkcd.com/"<>#,"Images"][[2]]&

Penggunaan dengan nomor:

%@"1500"

Penggunaan tanpa nomor:

%@""
Vitaliy Kaurov
sumber