แสดง xkcd


36

xkcd เป็นคอมมิคที่ทุกคนชื่นชอบและคุณจะเขียนโปรแกรมที่จะนำอารมณ์ขันมาให้พวกเราทุกคน
วัตถุประสงค์ของคุณในการท้าทายนี้คือการเขียนโปรแกรมซึ่งจะใช้ตัวเลขเป็นอินพุตและแสดงว่า xkcd และหัวเรื่อง - ข้อความ (ข้อความ mousover)

อินพุต

โปรแกรมของคุณจะใช้จำนวนเต็มบวกเป็นอินพุต (ไม่จำเป็นต้องมีหนึ่งตัวที่มีการ์ตูนที่ถูกต้อง) และแสดงว่า xkcd: ตัวอย่างอินพุต 1500 ควรแสดงการ์ตูน "Upside-Down Map" ที่ xkcd.com/1500 จากนั้นพิมพ์ข้อความชื่อเรื่องลงในคอนโซลหรือแสดงด้วยภาพ

เนื่องจากความใกล้ชิดของพวกเขาข้ามช่องทางมีความตึงเครียดมายาวนานระหว่างเกาหลีเหนือและสหราชอาณาจักรบริเตนใหญ่และไอร์แลนด์เหนือ 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:

นอกเหนือจากกันแล้วฉันสงสัยว่าสคริปต์การแยกวิเคราะห์ xkcd.com- ที่เขียนไม่ดีจำนวนมากจะใช้ชื่อนี้ (หรือ ;; "'' {<< ['ข้อความวางเมาส์นี้"

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

โปรแกรมของคุณควรจะสามารถทำงานได้โดยไม่ต้องป้อนข้อมูลใด ๆ และทำงานเดียวกันกับ xkcd ล่าสุดที่พบใน xkcd.com และควรแสดงรายการล่าสุดเสมอแม้ว่าจะมีรายการใหม่เกิดขึ้น

คุณไม่จำเป็นต้องรับภาพโดยตรงจาก xkcd.com คุณสามารถใช้ฐานข้อมูลอื่นได้ตราบใดที่มันเป็นข้อมูลล่าสุดและมีอยู่แล้วก่อนที่ความท้าทายนี้จะเกิดขึ้น ตัวย่อ URL คือ URL ที่ไม่มีจุดประสงค์อื่นนอกจากการเปลี่ยนเส้นทางไปยังที่อื่นไม่ได้รับอนุญาต

คุณสามารถแสดงภาพในแบบที่คุณเลือกรวมถึงในเบราว์เซอร์ อย่างไรก็ตามคุณอาจไม่แสดงส่วนหนึ่งของหน้าอื่นใน iframe หรือคล้ายกันโดยตรง ชี้แจง: คุณไม่สามารถเปิดหน้าเว็บมาก่อนถ้าคุณต้องการที่จะใช้เบราว์เซอร์ที่คุณต้องสร้างหน้าใหม่ คุณต้องแสดงภาพจริง - ไม่อนุญาตให้ส่งไฟล์รูปภาพ

คุณสามารถจัดการกับกรณีที่ไม่มีภาพสำหรับการ์ตูนที่เฉพาะเจาะจง (เช่นเป็นแบบโต้ตอบหรือโปรแกรมถูกส่งผ่านจำนวนที่มากกว่าจำนวนการ์ตูนที่เผยแพร่) ด้วยวิธีการที่เหมาะสมตามที่คุณต้องการรวมถึงการโยนข้อยกเว้น หรือพิมพ์สตริงอักขระเดี่ยวอย่างน้อยที่สุดตราบใดที่มันแสดงถึงผู้ใช้ว่าไม่มีภาพสำหรับอินพุตนั้น

คุณสามารถแสดงภาพและส่งออกข้อความหัวข้อหรือส่งข้อความข้อผิดพลาดสำหรับการ์ตูนที่ไม่ถูกต้อง ไม่อนุญาตให้ใช้เอาต์พุตอื่น

นี่เป็นความท้าทายของการดังนั้นจำนวนไบต์ที่น้อยที่สุดจึงเป็นผู้ชนะ


1
@LukeFarritor คุณสามารถแสดงภาพและเอาท์พุทข้อความไตเติ้ลหรือแสดงข้อความข้อผิดพลาดบางรูปแบบสำหรับการ์ตูนที่ไม่ถูกต้อง
Pavel

9
ถ้าขนาดตัวอย่างของคุณเป็น 1 import antigravityในหลาม;)
เวย์นเวอร์เนอร์

15
ตลกจริงแล้วn=404 xkcd.com/404เป็นหน้า 404
Magic Octopus Urn

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 เท่านั้น
ปาเก็ตตี้

คุณอาจไม่จำเป็นต้องใส่เครื่องหมายคำพูดรอบแอตทริบิวต์ src
Conor O'Brien

ฉันไม่คิดว่าคุณต้องการ?ในกลุ่มการแข่งขันครั้งแรก คุณสามารถใช้-pและ$_=$2แทนที่จะเป็นprint$2แต่จากนั้นข้อความชื่อเรื่องจะถูกพิมพ์หลังจากปิด feh เท่านั้น ไม่แน่ใจว่าถูกต้องหรือไม่
m-chrzan

@ m-chrzan ใช่ดูเหมือนว่าฉันสามารถวางจำนวนลังเลที่นั่นขอบคุณ ฉันคิดเกี่ยวกับการใช้-pแต่ไม่แน่ใจว่า OP จะรู้สึกอย่างไรกับมัน
ปาเก็ตตี้

@ ConorO'Brien น่าเสียดายที่แรนดัลสังเกตการเขียนโค้ด HTML ที่ดี ...
ปาเก็ตตี้

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 ที่ช่วยประหยัดไบต์โดยใช้การกำหนดแบบอินไลน์

หากไม่มีการโต้แย้งจะถูกส่งผ่านไปแล้ว$argsมันจะว่างเปล่าและมันก็จะได้รับการ์ตูนปัจจุบัน ดาวน์โหลดรูปภาพโดยจับคู่รูปภาพที่มีข้อความ alt ลงในไฟล์ในไดเรกทอรีที่กำลังใช้งานอยู่ของสคริปต์ จากนั้นแสดงด้วยมุมมองเริ่มต้นของ jpg ข้อความ alt จะปรากฏขึ้นเพื่อคอนโซล 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 วิธีการที่ดีในคำตอบของคุณ สิ่งที่ต้องพิจารณาในครั้งต่อไป
Matt

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 เพื่อวนซ้ำผ่านimgแท็กของ DOM จนกว่าจะพบกับข้อความชื่อ

สตรีมแบบไบนารีจะอ่านจาก URL รูปภาพและแสดงผลเป็นบิตแมปโดยใช้ GDIPlus จากนั้นจะแสดงใน GUI ขนาดอัตโนมัติที่มีคำแนะนำเครื่องมือจริงเพื่อให้มันทำงานเหมือนกับเว็บไซต์

นี่คือกรณีทดสอบ ( _(859)):

)


4
มันจะดีกว่าถ้าคุณเพิ่มวงเล็บกลับเข้าไปในภาพ
Matt

ว้าวเพิ่งพบว่าฉันสามารถเรียกใช้ AutoIt ภายใต้ Wine บน Ubuntu ตอนนี้สิ่งที่ฉันต้องทำคือให้ IE ทำงานที่นั่น ในความคิดที่สอง ... +1 สำหรับคำตอบ
ElPedro

2
@ElPedro หากคุณมีซีพียูที่ทันสมัยให้ใช้ qemu KVM และ seamlessRDP (โดยทั่วไปคือ DIY parallels สำหรับ linux) แทนที่จะเป็นไวน์ สิ่งนี้รวมแอพ Windows เข้ากับเดสก์ท็อป linux ได้อย่างราบรื่นและมีความเข้ากันได้ 100% + GPU passthrough เพียงแค่ปลาย
mınxomaτ

ขอบคุณ @ mınxomaτ ฉันอาจให้ไป ฉันทำงานกับ Windows ได้ตลอดทั้งวันดังนั้นจึงชอบที่จะใช้ Linux (หลายรสชาติ) ออกจากงาน แต่ฉันก็สนใจที่จะทดลอง :) คำแนะนำที่ได้รับอย่างสุดซึ้ง
ElPedro

7

Powershell, 93 ไบต์

93 เวอร์ชันไบต์เพื่อใช้โปรแกรมดูรูปภาพในเครื่อง

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

บันทึก 2 ไบต์โดยลบ doublequotes ที่ไม่จำเป็นออกแล้วล็อตอื่นโดยใช้("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 (น่าจะเป็นความคิดเห็น แต่ชื่อเสียงต่ำ)

แต่จะเป็นการเปิดแท็บ / หน้าต่างใหม่ในเบราว์เซอร์เริ่มต้นและสิ่งอื่น ๆ ซึ่งจะช่วยประหยัดไบต์

iwr เป็นชื่อแทน Invoke-WebRequest

sapsเป็นนามแฝงStart-Processที่เปิด 'มัน' ในบริบทเริ่มต้น


ข้ามขอบของกฎเกี่ยวกับการเปิดเว็บเพจที่มีอยู่เพราะนี่เป็นเพียงการเปิดเบราว์เซอร์โดยตรงที่. jpg (หรืออะไรก็ตาม) ที่มีอยู่แล้ว แต่เป็นคำตอบที่ดี
AdmBorkBork

@TimmyD อาจมีการเข้าใจผิดที่นี่แล้ว - ผมถือว่าคุณสามารถใช้หน้าเว็บ xkcd ตัวเอง - คุณก็สามารถเปลี่ยนsapsไปiwrและผนวก `-OutF x.jpg ii. x *` เพื่อท้ายที่สุดถ้าคุณต้องการที่จะเปิดให้บริการในท้องถิ่นเริ่มต้น โปรแกรมดูรูปภาพ
colsw

1
OP ระบุว่าคุณไม่ได้รับอนุญาตให้เปิดหน้าเว็บที่มีอยู่แล้ว ฉันคิดว่ารุ่น 93 ไบต์นั้นใช้ได้ แต่
ปาเก็ตตี้

ฉันไม่คิดว่ามันจะทำงานเหมือนเดิมทุกครั้งถ้าคุณให้หมายเลขที่ใช้งานได้แล้วตัวเลขที่ไม่ได้ทำงาน มันจะเปิดภาพที่มีอยู่จากการทำงานก่อนหน้านี้
Matt

ฉันยอมรับเวอร์ชัน 93 ไบต์ แต่เวอร์ชันที่สั้นกว่าของคุณละเมิดเงื่อนไขของตัวต่อ
Pavel

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 empty:
สำหรับ x = ''

กรณีเมื่อรูปภาพเป็น jpeg:
สำหรับ x = 10 (jpeg)

x = 859:
x = 859


ฉันสงสัยว่าจำเป็นต้องแสดงภาพในมิติที่ถูกต้องหรือไม่ plot.new();rasterImage(...)เมื่อผมเล่นรอบกับความท้าทายนี้ผมก็ไม่ได้ทำ
Billywob

@Billywob มันจะถูกบิดเบือนอย่างสมบูรณ์เนื่องจากขนาดเริ่มต้นสำหรับพล็อตคือ 7x7 นิ้ว เป็นความจริงที่ว่า OP ไม่ได้ขอภาพที่จะไม่บิดเบี้ยวอย่างชัดเจน แต่ฉันชอบมันมากกว่านี้ :) ฉันกำลังพิจารณาที่จะกำจัดมันxaxsและyaxsผลที่ตามมาก็คงเป็นสัดส่วน
plannapus


2

Python 2.7, 309 299 295 274 ไบต์

โปรแกรมเต็มรูปแบบ แน่นอนว่าเล่นกอล์ฟได้มากกว่า แต่การอ่านการ์ตูน xkcd มานานฉันก็ไม่สามารถผ่านได้

หากไม่มีการป้อนข้อมูลผ่านจะได้รับการ์ตูนปัจจุบัน หากหมายเลขการ์ตูนที่ถูกต้องถูกส่งผ่านเป็นอินพุตก็จะได้รับการ์ตูนนั้น หากมีการป้อนข้อมูลที่ไม่ถูกต้อง (ไม่ใช่ตัวเลขการ์ตูนในช่วงที่ถูกต้อง) ส่งผ่านข้อผิดพลาด

ข้อเสนอแนะใด ๆ เกี่ยวกับวิธีการลดจำนวนไบต์ยินดีต้อนรับ! จะกลับมาอีกครั้ง (และเพิ่มคำอธิบาย) เมื่อฉันมีเวลามากขึ้น

-10 ไบต์ขอบคุณ @Dopapp

-21 ไบต์ขอบคุณ @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]

1
คุณสามารถเปลี่ยนtry:...และexcept:...ไปที่try:n=...และexcept:n=''ช่วยให้คุณประหยัด 10 ไบต์
แดเนียล

1
ทำไมคุณถึงมีtryคำสั่ง ข้อมูลจำเพาะของโปรแกรมบอกว่าคุณจะได้รับจำนวนเต็มบวกเสมอ
Kade

@Shebang มันควรจะกลับการ์ตูนล่าสุดเมื่อไม่มีการป้อนข้อมูล ฉันไม่สามารถจัดการกรณีนี้ได้โดยไม่สนใจข้อผิดพลาดในการป้อนข้อมูล
Ioannes

1
@ โจอันเนสทำไมไม่ใช้raw_input()? โดยค่าเริ่มต้นผู้ใช้สามารถกด[Enter]และnจะมีสตริงที่ว่างอยู่แล้ว หากคุณลบ block ลองยกเว้นและt=u.urlopen(h+x+n).read() -> t=u.urlopen(h+x+raw_input()).read()คุณได้รับมันลงไปที่ 274 ไบต์
Kade

งานนี้ไม่ได้เพราะ URL รูปภาพ xkcd httpsใช้ อย่างไรก็ตามมันยังคงใช้ได้เพราะมันทำงานในเวลาโพสต์ หากต้องการให้ทำงานตอนนี้ให้เปลี่ยนบรรทัดที่ 3 เพื่อเริ่มต้นด้วยh='https://'+1 ไบต์
Mego

2

PHP, 42 ไบต์

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

บันทึกเป็นไฟล์และเริ่มทำงานในเว็บเซิร์ฟเวอร์ที่คุณเลือก


1
ยินดีต้อนรับสู่ PPCG! ฉันไม่รู้ PHP แต่ดูเหมือนจะไม่เป็นส่วนหนึ่งของรหัสของคุณที่ดึงข้อความชื่อภาพ?
Pavel

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/สามารถบันทึกได้17 ไบต์ ( ) หากสามารถลบพร็อกซีที่เชื่อมต่อกับ xkcd.com ได้ ( เมตาโพสต์เกี่ยวกับเรื่องนี้ )

ตัวอย่างการทดสอบ

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.