Bir xkcd göster


36

xkcd, herkesin en sevdiği web komutanlığıdır ve hepimize biraz daha mizah getirecek bir program yazacaksınız.
Bu zorluğun amacı, girdi olarak bir sayı alacak bir program yazmak ve bu xkcd ve başlık metnini (mousover metni) görüntülemektir.

Giriş

Programınız girdi olarak pozitif bir tamsayı alır (zorunlu olarak geçerli bir çizgi romanının bulunması zorunlu değildir) ve xkcd'yi görüntüler: örneğin, 1500'ün bir girişi xkcd.com/1500 adresinde "Upside-Down Map" çizgi romanını göstermelidir, ve sonra başlık metnini konsola yazdırın veya görüntüyle görüntüleyin.

Kanal boyunca yakınlıklarından dolayı, Kuzey Kore ile Büyük Britanya Birleşik Krallığı ve Güney İrlanda arasında uzun bir süredir gerilim var. 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 durumu 2, n = 859 için:

Beyinleri bir kenara, ne kadar kötü yazılmış xkcd.com-ayrıştırma komut dosyalarının bu başlıkta kaçınacağını merak ediyorum (veya ;; "'' {<< ['bu mouseover metni."

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

Programınız ayrıca herhangi bir giriş yapmadan da çalışabilmeli ve aynı görevi xkcd.com adresinde bulunan en son xkcd için gerçekleştirebilmeli ve yenisi başladığında bile her zaman en sonuncuyu göstermelidir.

Görüntüyü doğrudan xkcd.com adresinden almak zorunda değilsiniz, başka bir veri tabanını güncel olduğu ve bu zorluk çıkmadan önce zaten mevcut olduğu sürece kullanabilirsiniz. URL kısaltmalarına, yani başka bir yere yönlendirilmekten başka bir amacı olmayan URL'lere izin verilmez.

Görüntüyü, tarayıcıda dahil olmak üzere seçtiğiniz herhangi bir şekilde görüntüleyebilirsiniz. Sen olabilir değil , ancak, doğrudan bir iframe veya benzeri başka bir sayfaya bir kısmını gösterir. AYDINLATMA: önceden var olan bir web sayfasını açamazsınız, tarayıcıyı kullanmak istiyorsanız yeni bir sayfa oluşturmanız gerekir . Ayrıca bir görüntü de göstermelisiniz - görüntü dosyası çıktısına izin verilmez.

Bir istisna atmak da dahil olmak üzere herhangi bir makul şekilde, belirli bir çizgi roman için resim olmadığı (örneğin etkileşimli olduğu veya programın serbest bırakılan çizgi roman miktarından daha büyük bir sayıdan geçtiği) durumuyla ilgilenebilirsiniz. veya en azından tek karakterli bir dizgenin çıktısını almak, bir şekilde kullanıcıya bu girdi için bir görüntü olmadığını gösterdiği sürece.

Yalnızca bir resmi görüntüleyebilir ve başlık metnini çıkartabilir veya geçersiz bir çizgi roman için bir hata mesajı yazdırabilirsiniz. Diğer çıktılara izin verilmiyor.

Bu bir mücadelesidir, bu yüzden en az bayt kazanır.


1
@LukeFarritor Yalnızca görüntüyü görüntüleyebilir ve başlık metnini çıkartabilir veya geçersiz bir çizgi roman için bir tür hata mesajı yazdırabilirsiniz.
Pavel,

9
Örnek büyüklüğün 1 ise import antigravity, Python;)
Wayne Werner

15
Komik gerçek n=404 xkcd.com/404 bir 404 sayfadır.
Magic Octopus Urn

11
xkcd is everyone's favorite webcomic [Alıntı gerekli ]
Sanchises

11
Test
senaryosu

Yanıtlar:


13

Perl + curl + feh, 86 84 75 bayt

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

-pAnahtarı gerektirir . Bunu bayt sayımı ile hesapladım.


@Matt Denedim tüm çizgi roman üzerinde çalıştı. Bu yüzden sadece alt-metin ile görüntüleri eşleşir.
bir

Src niteliği etrafındaki alıntılara ihtiyacınız olmayabilir.
Conor O'Brien,

?İlk gruptaki gruba ihtiyacın olduğunu sanmıyorum . Sen kullanabilirsiniz -pve $_=$2yerine print$2, ama sonra başlık metni yalnızca yazdırılır sonra feh kapatılır. Bunun geçerli olup olmadığından emin değilim.
m-chrzan

@ m-chrzan Evet, isteksiz miktar belirleyiciyi oraya bırakabilirim, teşekkürler. Kullanmayı düşündüm -pama OP'nin bu konuda ne hissedeceğinden emin değildim.
bir

@ ConorO'Brien Ne yazık ki Randall, iyi HTML kodlama uygulamalarını gözlemler ... ve fiyatları yakalama, daha sonra Perl'deki backtick'lerin çalışma şeklinden dolayı argümanları alıntılamaz.
bir

9

PowerShell v3 + 110 99 107 103 Bayt

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

Satır içi atamaları kullanarak bazı baytları kurtarmanıza yardımcı olan Timmy'ye teşekkür ederiz.

Herhangi bir argüman iletilmezse $argsnull olur ve sadece o anki çizgi filmi alır. Resmi alt metinle eşleştirerek komut dosyasının geçerli dizindeki dosyaya indirin. Sonra jpg'nin varsayılan görüntüleyicisi ile görüntüleyin. Alt metin daha sonra konsolda görüntülenir. iwrbir takma adInvoke-WebRequest

Eğer sayı geçtiğinde (veya bu konuda herhangi bir geçersiz girdi yoksa), işlem en az 404 hatasıyla başarısız olur.

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.

Sadece şimdi bu alt hakkındaki yorum ayrıcalığımı gördüm, çok benzer bir cevabı
colsw

@ConnorLSW Cevabınıza güzel bir yaklaşım. Bir dahakine düşünecek şeyler.
Matt,

8

AutoIt , 440 bayt

Evet, uzun, ama kararlı.

#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

Her şeyden önce, bu siteyi kazımak için RegEx kullanmaz (çünkü bunu tüm çizgi romanlarda test etmek için zamanım yok), ancak bunun yerine, imgbaşlıkları metin içeren bir tane bulana kadar DOM'in etiketleri arasında yineleme yapmak için Internet Explorer API'sini kullanıyor .

İkili akış resim URL'sinden okunur ve GDIPlus kullanılarak bir bitmap halinde oluşturulur. Bu daha sonra, web sitesinin neredeyse aynen davranmasını sağlamak için gerçek bir araç ipucuyla birlikte otomatik boyutta bir GUI'de görüntülenir.

İşte bir test durumu ( _(859)):

)


4
Desteği görüntüye geri eklerseniz daha iyi olur.
Matt,

Vay, az önce AutoIt'i Wine altında Ubuntu'da çalıştırabileceğimi öğrendim. Şimdi tek yapmam gereken IE'nin üzerinde çalışmasını sağlamak. İkinci düşüncelerde ... Cevap için +1
ElPedro

2
@ElPedro Eğer modern bir işlemciniz varsa, şarap yerine qemu KVM ve seamlessRDP (linux için temelde DIY paralellikler) kullanın. Bu, Windows uygulamalarını sorunsuz bir şekilde linux masaüstüne entegre eder ve% 100 uyumluluk + GPU geçidi vardır. Sadece bir ipucu.
mınxomaτ

@ Mınxomaτ teşekkür ederiz. Buna bir şans verebilirim. Bütün gün Windows ile çalışıyorum, bu yüzden iş dışında Linux (çeşitli tatlar) kullanmayı tercih ediyorum ama her zaman deneyimle ilgileniyorum :) İpucu minnetle alındı.
ElPedro

7

Powershell, 93 Bayt

Yerel resim görüntüleyiciyi kullanmak için 93 Bayt sürümü.

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

Gereksiz çift tırnak işaretlerini kaldırarak 2 bayt, daha sonra ("http:"+$n.src)bunun yerine başka bir lot kullanarak kaydedilmiş "https://"+$n.src.trim("/")- imgsrc //zaten bununla birlikte gelir ve xkcd https gerektirmez.

$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 cevabına son derece benzer, (muhtemelen bir yorum olmalı ama itibarı düşük olmalı)

Bunun yerine, varsayılan tarayıcıda yeni bir sekme / pencere ve bazı baytları kaydederek başka şeyler açılır.

iwr bir takma ad Invoke-WebRequest

sapsStart-Processvarsayılan bağlamda 'onu' açan bir diğer addır.


Mevcut bir web sayfasını açmakla ilgili kuralların kenarlarını süpürmek, çünkü bu sadece tarayıcıyı önceden varolan .jpg (ya da her neyse) adresinde doğrudan başlatmaktır, fakat güzel bir cevaptır.
AdmBorkBork 28:16

@TimmyD buraya yazıp yanlış anlaşılmış olabilir - Sana xkcd web sayfasını kendisi kullanabilir varsayılır - sadece değiştirebilir sapsiçin iwrekleme `-OutF x.jpg ve;. İi x *` sonuna kadar bunu yerel varsayılan açmak istiyorsanız resim görüntüleyici.
colsw

1
OP, önceden var olan bir web sayfasını açmanıza izin verilmediğini belirtti. Bence 93 bayt versiyonu ince olsa
bir spaghetto

Ben bu işleri bir numara verirsen hep aynı işe sanmıyorum o değil bir numara. Önceki çalışmadan var olan görüntüyü açacaktır.
Matt,

93 byte versiyonunu kabul ediyorum, fakat kısa olanınız bulmacanın koşullarını ihlal ediyor.
Pavel

4

R, 358 328 310 298 bayt

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

Yeni çizgiler ve yorumlarla:

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
}

Screenshots arasında test vakaları:

x = 1500 için: x = 1500 (png) için

x boş için:
x = '' için

resim bir jpeg olduğunda durum:
x = 10 (jpeg) için

X = 859:
X = 859


Görüntünün doğru boyutlarda gösterilmesi gerekip gerekmediğini merak ediyorum. Bu sorunla uğraşırken basitçe yaptım plot.new();rasterImage(...).
Billywob

@Billywob Tamamen arsa için varsayılan boyut 7x7 inç olduğundan tamamen bozulmuştur. OP'nin açıkça görüntünün bozulmamasını istemediği doğrudur, ancak bunu bu şekilde tercih ederim :) Ancak kurtulmayı düşünüyorum xaxsve yaxssonuç olarak orantılı olacaktır.
plannapus 28:16


2

Python 2.7, 309 299 295 274 bayt

Tam program Kesinlikle daha fazla golf oynayabilir, ancak uzun zamandır xkcd çizgi romanını okumak bu geçişe izin veremedim (bunun gelecekte xkcd'yi kolayca taramak için faydalı olup olmadığını kim bilebilir).

Herhangi bir giriş iletilmezse, geçerli çizgi mesajı alır. Geçerli bir çizgi roman numarası girdi olarak iletilirse, bu çizgi roman görüntülenir. Geçersiz bir giriş (geçerli aralıkta çizgi olmayan bir sayı değil) iletilirse bir hata atar.

Bayt sayısını azaltma konusunda herhangi bir öneri bekliyoruz! Daha fazla zamanım olduğunda tekrar (ve bir açıklama ekleyeceğim).

@Dopapp sayesinde -10 bayt

@Shebang sayesinde -21 bayt

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
Değişebilirsin try:...ve except:...için try:n=...ve except:n=''sana 10 bayt tasarruf toplam
Daniel

1
Neden bir trydeyiminiz var? Programın özelliği her zaman pozitif bir tamsayı elde edeceğinizi söylüyor.
Kade

@Shebang, giriş olmadığında da en son çizgi rotayı döndürmelidir. Giriş hatası haricinde bu durumu yönetemedim.
Ioannes

1
@Joannes Neden kullanmıyorsunuz raw_input()? Kullanıcı varsayılan olarak basabilir [Enter]ve nboş dizeyi yine de içerecektir. Eğer bu hariç tutma bloğunu kaldırırsanız ve t=u.urlopen(h+x+n).read() -> t=u.urlopen(h+x+raw_input()).read()onu 274 bayta indirirseniz.
Kade,

Bu artık çalışmaz, çünkü xkcd resim URL'leri kullanır https. Ancak, gönderim sırasında çalıştığı için hala geçerlidir. Şimdi çalışmasını sağlamak h='https://'için +1 bayt ile başlamak üzere satır 3'ü değiştirin .
Mego

2

PHP, 42 bayt

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

Bir dosyaya kaydedin ve istediğiniz web sunucusunda ateşleyin


1
PPCG'ye Hoşgeldiniz! PHP bilmiyorum ama kodunuzun resmin başlık metnini alan bir parçası gibi görünmüyor?
Pavel,

1

JavaScript + HTML, 124 + 18 = 142 bayt

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'nun buradaki cevabı sayesinde çapraz kaynaklı çözüm .

//crossorigin.me/Xkcd.com'a bağlanmak için gereken proxy çıkarılabiliyorsa 17 bayt ( ) kaydedilebilir ( bununla ilgili meta gönderim ).

Test Parçacığı

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 + İstekler + PIL, 192 186 bayt

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

Çizgi romanı içeren (çalıştırıldığı sistemde varsayılan olan) bir resim görüntüleyici açar ve başlık metnini konsola gönderir.


1

Wolfram Dili 45 bayt (Mathematica)

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

Number ile kullanımı:

%@"1500"

Numarasız kullanım:

%@""
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.