Hiển thị xkcd


36

xkcd là webcomic yêu thích của mọi người và bạn sẽ viết một chương trình mang lại sự hài hước hơn một chút cho tất cả chúng ta.
Mục tiêu của bạn trong thử thách này là viết một chương trình sẽ lấy một số làm đầu vào và hiển thị xkcd đó và văn bản tiêu đề của nó (văn bản mousover).

Đầu vào

Chương trình của bạn sẽ lấy số nguyên dương làm đầu vào (không nhất thiết phải là số có truyện tranh hợp lệ) và hiển thị xkcd: ví dụ: đầu vào 1500 sẽ hiển thị truyện tranh "Bản đồ lộn ngược" tại xkcd.com/1500, và sau đó in văn bản tiêu đề của nó lên bàn điều khiển hoặc hiển thị nó với hình ảnh.

Do sự gần gũi của họ trên kênh, từ lâu đã có căng thẳng giữa Bắc Triều Tiên và Vương quốc Liên hiệp Anh và Nam 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.

Trường hợp thử nghiệm 2, cho n = 859:

Não bộ sang một bên, tôi tự hỏi có bao nhiêu tập lệnh phân tích xkcd.com được viết kém sẽ phá vỡ tiêu đề này (hoặc ;; "'' {<< ['văn bản di chuột này."

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

Chương trình của bạn cũng có thể hoạt động mà không cần bất kỳ đầu vào nào và thực hiện cùng một tác vụ cho xkcd gần đây nhất được tìm thấy tại xkcd.com và nó sẽ luôn hiển thị cái gần đây nhất ngay cả khi một cái mới xuất hiện.

Bạn không cần phải lấy hình ảnh trực tiếp từ xkcd.com, bạn có thể sử dụng một cơ sở dữ liệu khác miễn là nó được cập nhật và đã tồn tại trước khi thử thách này xảy ra. Việc rút ngắn URL, nghĩa là các url không có mục đích nào khác ngoài việc chuyển hướng đến một nơi khác, không được phép.

Bạn có thể hiển thị hình ảnh theo bất kỳ cách nào bạn chọn, kể cả trong trình duyệt. Bạn có thể không , tuy nhiên, trực tiếp hiển thị một phần của một trang khác trong một iframe hoặc tương đương. XÁC NHẬN: bạn không thể mở một trang web có sẵn, nếu bạn muốn sử dụng trình duyệt, bạn phải tạo một trang mới . Bạn cũng phải thực sự hiển thị một hình ảnh - không cho phép xuất ra một tệp hình ảnh.

Bạn có thể xử lý trường hợp không có hình ảnh cho một truyện tranh cụ thể (ví dụ: nó có tính tương tác hoặc chương trình được thông qua một số lượng lớn hơn số lượng truyện tranh đã được phát hành) theo bất kỳ cách hợp lý nào bạn muốn, kể cả ném ngoại lệ hoặc in ra ít nhất một chuỗi ký tự, miễn là bằng cách nào đó nó biểu thị cho người dùng rằng không có hình ảnh cho đầu vào đó.

Bạn chỉ có thể hiển thị hình ảnh và xuất văn bản tiêu đề của nó hoặc xuất thông báo lỗi cho truyện tranh không hợp lệ. Đầu ra khác không được phép.

Đây là một thử thách , vì vậy ít byte nhất sẽ thắng.


1
@LukeFarritor Bạn chỉ có thể hiển thị hình ảnh và xuất văn bản tiêu đề hoặc xuất một số dạng thông báo lỗi cho truyện tranh không hợp lệ.
Pavel

9
Nếu kích thước mẫu của bạn là 1, import antigravitybằng Python;)
Wayne Werner

15
Thực tế hài hước n=404 xkcd.com/404 là một trang 404.
Bạch tuộc ma thuật Urn

11
xkcd is everyone's favorite webcomic [Cần dẫn nguồn ]
Chiếm

11
Trường hợp thử nghiệm: 859
betseg

Câu trả lời:


13

Perl + curl + feh, 86 84 75 byte

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

Yêu cầu -pchuyển đổi. Tôi đã tính đến điều này trong số byte.


@Matt Nó hoạt động trên tất cả các truyện tranh tôi đã thử. Nó chỉ phù hợp với hình ảnh với văn bản thay thế như vậy.
một spaghetto

Bạn có thể không cần các trích dẫn xung quanh thuộc tính src.
Conor O'Brien

Tôi không nghĩ bạn cần ?trong nhóm trận đấu đầu tiên. Bạn có thể sử dụng -p$_=$2thay vì print$2, nhưng sau đó văn bản tiêu đề chỉ được in sau khi đóng feh. Không chắc chắn nếu điều đó hợp lệ.
m-chrzan

@ m-chrzan Vâng, có vẻ như tôi có thể bỏ bộ định lượng miễn cưỡng ở đó, cảm ơn. Tôi đã nghĩ về việc sử dụng -pnhưng không chắc OP sẽ cảm thấy thế nào về nó.
một spaghetto

@ ConorO'Brien Thật không may Randall quan sát các thực tiễn mã hóa HTML tốt ... và việc ghi lại các trích dẫn không trích dẫn các đối số do cách backticks hoạt động trong Perl.
một spaghetto

9

PowerShell v3 + 110 99 107 103 byte

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

Cảm ơn Timmy vì đã giúp lưu một số byte bằng cách sử dụng các bài tập nội tuyến.

Nếu không có đối số nào được thông qua thì $argslà null và nó sẽ chỉ lấy truyện tranh hiện tại. Tải ảnh xuống, bằng cách ghép ảnh với văn bản thay thế, vào một tệp trong thư mục đang chạy của tập lệnh. Sau đó hiển thị nó với trình xem mặc định của jpg. Văn bản thay thế sau đó được hiển thị cho bàn điều khiển. iwrlà bí danh choInvoke-WebRequest

Nếu số được truyền (hoặc bất kỳ đầu vào không hợp lệ nào cho vấn đề đó) không khớp với quy trình sẽ thất bại với ít nhất là lỗi 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.

Chỉ nhận được đặc quyền nhận xét của tôi về phụ này ngay bây giờ, hãy xem câu trả lời rất giống
colsw

@ConnorLSW Cách tiếp cận tốt đẹp trong câu trả lời của bạn. Những điều cần suy nghĩ cho lần sau.
Matt

8

Tự động , 440 byte

Vâng, nó dài, nhưng nó ổn định.

#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

Trước hết, điều này không sử dụng RegEx để quét trang web (vì tôi không có thời gian để kiểm tra điều này trên tất cả truyện tranh), mà sử dụng API Internet Explorer để lặp qua các imgthẻ của DOM cho đến khi tìm thấy một trang có văn bản tiêu đề.

Luồng nhị phân được đọc từ URL hình ảnh và được hiển thị thành bitmap bằng GDIPlus. Điều này sau đó được hiển thị trong một GUI đẹp, có kích thước tự động với một chú giải công cụ thực tế để làm cho nó hoạt động gần như chính xác như trang web.

Đây là một trường hợp thử nghiệm ( _(859)):

)


4
Sẽ tốt hơn nếu bạn thêm khung trở lại vào hình ảnh.
Matt

Ồ, chỉ cần phát hiện ra rằng tôi có thể chạy AutoIt trong Wine trên Ubuntu. Bây giờ tất cả những gì tôi cần làm là để IE hoạt động ở đó. Về ý nghĩ thứ hai ... +1 cho câu trả lời
ElPedro

2
@ElPedro Nếu bạn có CPU hiện đại, hãy sử dụng qemu KVM và liền mạchRDP (về cơ bản là tương tự DIY cho linux) thay vì rượu vang. Điều này tích hợp các ứng dụng Windows liền mạch vào máy tính để bàn linux và có khả năng tương thích 100% + thông qua GPU. Chỉ là một mẹo.
mınxomaτ

Cảm ơn @ mınxomaτ. Tôi có thể cho nó đi. Tôi làm việc với Windows cả ngày vì vậy thích sử dụng Linux (nhiều hương vị khác nhau) nhưng tôi luôn thích thử nghiệm :) Mẹo nhận được rất nhiều.
ElPedro

7

Powershell, 93 byte

Phiên bản 93 Byte để sử dụng trình xem ảnh cục bộ.

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

Đã lưu 2 byte bằng cách loại bỏ các doublequote không cần thiết, sau đó sử dụng nhiều hơn bằng cách sử dụng ("http:"+$n.src)thay vì "https://"+$n.src.trim("/")- vì imgsrc //đã có sẵn trên đó và xkcd không yêu cầu 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("/"))

cực kỳ giống với câu trả lời của Matts powershell, (có lẽ nên là một bình luận nhưng uy tín thấp)

Thay vào đó, điều này sẽ mở một tab / cửa sổ mới trong trình duyệt mặc định và những thứ khác, lưu một số byte.

iwr là bí danh cho Invoke-WebRequest

sapslà một bí danh để Start-Processmở 'nó' trong ngữ cảnh mặc định.


Bỏ qua các quy tắc về việc mở một trang web hiện có, bởi vì đây chỉ là trực tiếp khởi chạy trình duyệt ở .jpg (hoặc bất cứ điều gì) có sẵn, nhưng một câu trả lời hay.
admBorkBork

@TimmyD có thể có hiểu lầm ở đây rồi - tôi cho rằng bạn có thể sử dụng trang web xkcd bản thân - bạn chỉ có thể thay đổi sapsđể iwrvà append '-OutF x.jpg;. Ii x * `đến cùng nếu bạn muốn nó mở mặc định địa phương xem ảnh.
colsw

1
OP chỉ định rằng bạn không được phép mở một trang web có sẵn. Phiên bản 93 byte tôi nghĩ là ổn mặc dù
một spaghetto

Tôi không nghĩ rằng điều này sẽ luôn hoạt động như nhau nếu bạn đưa ra một số hoạt động thì một số không hoạt động. Nó sẽ mở hình ảnh tồn tại từ lần chạy trước.
Matt

Tôi chấp nhận phiên bản 93 byte, nhưng phiên bản ngắn hơn của bạn vi phạm các điều kiện của câu đố.
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])}

Với những dòng và bình luận mới:

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
}

Ảnh chụp màn hình của các trường hợp thử nghiệm:

cho x = 1500: cho x = 1500 (png)

cho x trống:
cho x = ''

trường hợp khi hình ảnh là một jpeg:
cho x = 10 (jpeg)

x = 859:
x = 859


Tôi tự hỏi nếu nó cần thiết để hiển thị hình ảnh trong các kích thước chính xác. Khi tôi chơi xung quanh với thử thách này, tôi chỉ đơn giản là làm plot.new();rasterImage(...).
Billywob

@Billywob Vâng, nó sẽ bị biến dạng hoàn toàn vì kích thước mặc định cho cốt truyện là 7x7 inch. Đúng là OP đã không yêu cầu hình ảnh rõ ràng để không bị biến dạng nhưng tôi thích nó theo cách này :) Tuy nhiên tôi đang xem xét loại bỏ xaxsyaxsvì kết quả vẫn sẽ tương xứng.
plannapus


2

Python 2.7, 309 299 295 274 byte

Chương trình đầy đủ. Chắc chắn là dễ chơi hơn, nhưng đã đọc truyện tranh xkcd trong một thời gian dài, tôi không thể bỏ qua điều này (ai biết liệu điều này sẽ hữu ích trong tương lai để dễ dàng duyệt xkcd).

Nếu không có đầu vào nào được thông qua, hãy lấy truyện tranh hiện tại. Nếu một số truyện tranh hợp lệ được thông qua làm đầu vào thì lấy truyện tranh đó. Nếu một đầu vào không hợp lệ (không phải là một số truyện tranh trong phạm vi hợp lệ) được thông qua, sẽ gây ra lỗi.

Mọi đề xuất về cách giảm số byte đều được chào đón! Sẽ xem lại (và thêm lời giải thích) khi tôi có nhiều thời gian hơn.

-10 byte nhờ @Dopapp

-21 byte nhờ @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
Bạn có thể thay đổi try:...except:...thành try:n=...except:n='', tiết kiệm cho bạn tổng cộng 10 byte
Daniel

1
Tại sao bạn thậm chí có một trytuyên bố? Thông số chương trình nói rằng bạn sẽ luôn nhận được một số nguyên dương.
Kade

@Shebang nó cũng nên trả lại truyện tranh mới nhất khi không có đầu vào. Tôi đã không thể quản lý trường hợp này mà không khắc phục ngoại lệ lỗi đầu vào.
Ioannes

1
@Joannes Tại sao không sử dụng raw_input()? Theo mặc định, người dùng có thể nhấn [Enter]nsẽ chứa chuỗi rỗng. Nếu bạn loại bỏ khối thử ngoại trừ đó và t=u.urlopen(h+x+n).read() -> t=u.urlopen(h+x+raw_input()).read()bạn có giảm xuống còn 274 byte.
Kade

Điều này không còn hoạt động, bởi vì URL hình ảnh xkcd sử dụng https . Tuy nhiên, nó vẫn còn hiệu lực, bởi vì nó hoạt động tại thời điểm đăng. Để làm cho nó hoạt động ngay bây giờ, thay đổi dòng 3 để bắt đầu với h='https://'+1 byte.
Mego

2

PHP, 42 byte

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

Lưu vào một tệp và kích hoạt nó trong máy chủ web của bạn lựa chọn


1
Chào mừng đến với PPCG! Tôi không biết PHP, nhưng dường như không có một phần nào trong mã của bạn đang tìm nạp văn bản tiêu đề của hình ảnh?
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>

Giải pháp đa nguồn gốc nhờ câu trả lời của Kaiido tại đây .

17 byte ( //crossorigin.me/) có thể được lưu nếu proxy cần thiết để kết nối với xkcd.com có ​​thể bị trừ ( bài đăng meta về điều này ).

Kiểm tra đoạn trích

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 + Yêu cầu + 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"])

Mở trình xem hình ảnh (tùy theo mặc định trên hệ thống đang chạy) có chứa truyện tranh và đăng văn bản tiêu đề lên bảng điều khiển.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.