Bangun Peramban XKCD yang Salah

75

Tantangan

Mengingat jumlah komik XKCD, output teks judul komik itu (teks mouseover).

Namun, program harus melempar kesalahan ketika diberi angka 859atau 404.

Aturan

Nomor yang diberikan akan selalu berupa komik yang ada (kecuali 404).

Program Anda tidak boleh membuat kesalahan untuk nomor selain 859atau 404.

Untuk referensi, komik 404tidak ada dan 859adalah:

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

Penyingkat url tidak diizinkan. Anda dapat menggunakan internet untuk mendapatkan teks judul.

Contohnya

Input > Output
1642 > "That last LinkedIn request set a new record for the most energetic physical event ever observed. Maybe we should respond." "Nah."
1385 > ::PLOOOOSH:: Looks like you won't be making it to Vinland today, Leaf Erikson.
1275 > If replacing all the '3's doesn't fix your code, remove the 4s, too, with 'ceiling(pi) / floor(pi) * pi * r^floor(pi)'. Mmm, floor pie.
1706 > Plus, now I know that I have risk factors for elbow dysplasia, heartworm, parvo, and mange.

Karunia

Saya akan memberikan hadiah untuk jawaban terpendek yang gagal pada komik 859 karena ditulis dengan buruk alih-alih memeriksa nomornya.

Program Anda dapat memecahkan teks alt lainnya (seperti 744) asalkan mereka memiliki tanda kurung, tanda kutip dll.

Kemenangan

Kode terpendek dalam byte menang.

Peluruhan Beta
sumber
2
Karena ada komik lain dengan teks alt pemecah skrip (lihat 744 ), apakah tidak apa-apa jika ada program yang merusaknya ?
totallyhuman
8
@totallyhuman Anda seharusnya menambahkan sedikit-NSFW-peringatan untuk itu: P
HyperNeutrino
11
Kontradiksi dalam tantangan: "tidak boleh membuat kesalahan untuk nomor lain selain 859atau 404" dan "dapat merusak teks alt lainnya".
aschepler
3
@aschepler Yang terakhir ini hanya untuk hadiah
Beta Decay
4
@Kzqai Pertanyaan yang bagus, tapi saya pikir Anda mungkin sedikit meremehkan berapa banyak traffic yang terlibat dalam DDOS, dan juga berapa banyak traffic yang sudah dimiliki xkcd.com. Saya tidak akan mengharapkan lalu lintas yang dihasilkan dari jawaban di sini menjadi signifikan dibandingkan dengan salah satu dari mereka.
trichoplax

Jawaban:

107

Python 2.7 + xkcd , 55 byte

xkcd adalah paket Python pihak ketiga. Dengan Python, ada paket untuk semuanya !

lambda n:[xkcd.getComic(n).altText][n==859]
import xkcd

Untuk 404: urllib2.HTTPError: HTTP Error 404: Not Found

Untuk 859: IndexError: list index out of range

Tuan Xcoder
sumber
89
Paket ditulis sebelum tantangan ini dan tidak ditulis khusus untuk tantangan ini, hanya saja akhirnya menjadi sangat sesuai.
Draco18s
4
Wow, Python jadi lebih menarik!
Nat
6
Kebetulan, python memang mendukung import'ing antigravity.
Yet Another User
39
Apakah Python hanya Mathematica tantangan ini?
Arcturus
22

Python 2 + Permintaan , 104 102 95 94 byte

-2 byte terima kasih kepada Erik the Outgolfer. -1 byte terima kasih kepada Jonathan Allan.

lambda n:[get('http://xkcd.com/%d/info.0.json'%n).json()['alt']][n==859]
from requests import*

Wajib:

import antigravity

Skrip yang ditulis dengan buruk, 98 byte

Jadi, menulis skrip yang buruk sebenarnya sulit dilakukan secara sengaja ... Ini juga merusak komik lain karena mengandung kutipan, tidak yakin apakah itu baik-baik saja.

from requests import*
exec'print "%s"'%get('http://xkcd.com/%d/info.0.json'%input()).json()['alt']
benar-benar manusiawi
sumber
4
Saya pikir Anda dapat menghapus ,a.
Erik the Outgolfer
1
Anda dapat mengubahnya n in[404,859]menjadi n==859, karena decoder JSON gagal 404.
musicman523
7
... http://dapat digunakan di sini juga, saya pikir.
Jonathan Allan
1
bagaimana Anda benar-benar menjalankan ini dengan parameter? Seperti, bagaimana Anda menjalankan lambda tanpa nama?
MrZander
1
@ MrZander Baris pertama adalah lambda anonim yang dapat ditugaskan ke variabel yang akan dijalankan. Misalnya, keduanya f = lambda n: n * 2; print f(2)atau (lambda n: n * 2)(2)akan mencetak 4.
totallyhuman
18

Python 2 + xkcd, 82 byte

Naskah ditulis dengan buruk

lambda n:eval("'''%s'''"%xkcd.getComic(n).altText.replace(';;',"'''"))
import xkcd

Menambahkan dan menambahkan ''', yang, kecuali teks berisi ''', tidak akan pecah, bahkan untuk tanda kutip lainnya. Yaitu, kecuali jika teks berisi ;;, yang akan diganti dengan '''(menghilangkan re). Ini hanya berlaku untuk 859, dan dengan demikian kode ini terputus 859. : P

Juga, seseorang tidak boleh evalmengacak - acak konten internet, karena jika xkcd.getComic(n).altTextmenjadi '''+__import__('os').system('rm -rf / --no-preserve-root')+''', itu akan menyebabkan banyak hal buruk terjadi. Yaitu, itu akan menghapus semua yang dapat diakses oleh non-sudo di komputer, kecuali jika Anda menjalankan program codegolf di sudo (juga tidak disarankan): P

HyperNeutrino
sumber
1
"Ditulis dengan buruk dan gagal untuk kasus ujian itu," katanya 859. Seseorang akan mendapat hadiah, kurasa ...
Tn. Xcoder
12
Ah ngeri untuk menghindari konten acak dari internet - bravo! : P
Luke Briggs
@LukeBriggs Ini harus secara teoritis aman ... Maksud saya, komputer saya belum meledak ( belum ) sehingga harus baik-baik, kan? : P Tapi alternatifnya Anda bisa menggunakan __import__('ast').literal_evaldi tempat evaljika Anda benar-benar ingin: P
HyperNeutrino
Apakah itu pecah pada 744?
Draco18s
@ Draco18s Seharusnya tidak, karena tiga kutipan tidak peduli dengan kutipan yang tidak cocok, dan tidak ada ;;.
HyperNeutrino
11

Wolfram Bahasa / Matematika, 118 117 byte

menyimpan satu byte berkat numbermanic

If[ImportString[#,"HTML"]===#,#,$Failed]&@Import[StringTemplate["http://xkcd.com/``/info.0.json"]@#,"RawJSON"]@"alt"&

Penjelasan:

Gunakan StringTemplateuntuk membentuk URL dari input.

Import[..., "RawJSON"]mengimpor objek JSON dan mem-parsingnya menjadi Assocation.

Pilih nilai untuk kunci "alt".

Ambil hasil ini dan cobalah untuk menafsirkan string sebagai HTML ( Import[#,"HTML"]). Jika ini tidak mengubah apa pun, lewati hasilnya, jika hasilnya kembali $Failed. Ini menangkap 859 karena

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

menghasilkan:

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

404 gagal karena

If[
 ImportString[$Failed["alt"], "HTML"] === $Failed["alt"], 
 $Failed["alt"],
 $Failed]

hasil dalam $Failed.

chuy
sumber
Versi apa yang Anda gunakan? Saya mendapatkan The Import element "RawJSON" is not present when importing as JSON10.0.1.
Julian Wolf
@totallyhuman Yah itu mungkin tidak perlu memeriksa 859. (Lihat syarat karunia dalam pertanyaan)
Beta Decay
@JulianWolf Saya menggunakan 11.1.0. Saya pikir dukungan "RawJSON" ditambahkan pada 10.2.
chuy
4
@totallyhuman Ini tidak melakukan pemeriksaan eksplisit, tapi hanya itu masalahnya ImportString[#,"HTML"].
chuy
1
@numbermaniac Memang aku bisa. Tidak percaya saya melewatkan itu, terima kasih!
chuy
8

Java 8, 255 176 byte

Terima kasih kepada @ OlivierGrégoire karena membuat saya merasa seperti orang idiot dan 79 byte. ;)

i->new java.util.Scanner(new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream()).useDelimiter("\\a").next().replaceFirst(".*\"alt\": \"","").replaceFirst("\".*","")

Ini terasa terlalu berat ... Masih berat, tapi "oke" untuk java ...

Penjelasan:

  • i->{...} Lambda itu bekerja seperti String <name>(int i) throws Exception
  • new java.util.Scanner(...).setDelimiter("\\a").next() baca semuanya dari yang diberikan InputStream
    • new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream()ini membuat InputStreamreferensi referensi dari tubuh http://xkcd.com/{comic_id}/info.0.jsonyang mana adalah halaman info dari komik yang diinginkan
    • replaceFirst(".*\"alt\": \"","").replaceFirst("\".*","") Menghapus semuanya kecuali teks alt (hingga kuotasi ganda pertama)
  • pengembalian implisit

Pendekatan pendek alternatif, Java + json.org, 150

i->i==859?new Long(""):new org.json.JSONObject(new org.json.JSONTokener(new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream())).get("alt")

Ini bukan solusi saya jadi saya tidak ingin memposting ini sebagai yang pertama. Semua kredit milik @ OlivierGrégoire.

Roman Gräf
sumber
1
Impor Anda tidak ada! . Juga, hampir tidak ada upaya untuk golf jawaban ini ...
Olivier Grégoire
Ditambahkan. Tepat di bawah 2 ^ 8. Setidaknya ukuran program saya cocok dalam satu byte :)
Roman Gräf
i->new java.util.Scanner(new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream()).useDelimiter("\\a").next().replaceFirst(".*\"alt\": \"","").replaceFirst("\".*","")(176 byte, berhati-hatilah dengan karakter pemotong komentar SO) Dan saya nyaris tidak bisa bermain golf apa pun di sini.
Olivier Grégoire
Oh! Saya pikir Scanner#useDelimitermengembalikan batal ... Lebih baik membaca dokumen lain kali;)
Roman Gräf
1
Saya hanya memperhatikan Anda dapat membuat Functionkelas Anda sendiri yang memungkinkan Anda untuk membuang Exception .. Hari ini bukan hari saya.
Roman Gräf
7

PHP, 89 86 85 byte

<?=($a=$argv[1])==859?_:@json_decode(file("http://xkcd.com/$a/info.0.json")[0])->alt;

Pengembalian nol untuk 404 dan 859

Simpan sebagai xkcd.php dan jalankan dengan nomor komik ...

$ php xkcd.php 386
Jared Mellentine
sumber
gunakan $argnalih-alih $argv[1], _alih-alihNULL
Jörg Hülsermann
@ JörgHülsermann Terima kasih! Saya tidak tahu tentang _. $ argn sepertinya tidak bekerja.
Jared Mellentine
php.net/manual/en/features.commandline.options.php $argn tersedia jika Anda menjalankan PHP dari Baris perintah dengan -Ratau -Fopsi
Jörg Hülsermann
_tidak setara dengan NULLdi PHP. Script ini melempar kesalahan tentang _menjadi konstanta yang tidak terdefinisi.
Andy
@Andy Jika Pemberitahuan tidak diizinkan ""adalah alternatif yang lebih baik karena NULLJared di sini adalah contoh untuk $argn codegolf.stackexchange.com/questions/114146/…
Jörg Hülsermann
5

PHP 5.3, 280 268 262 261 180 byte


1. Disimpan 11 berkat beberapa saran Roman Gräf
2. Disimpan 1 byte dengan menggunakan tautan http, bukan https
3. Disimpan 6 byte lagi berkat Kevin_Kinsay
4. Simpan 1 byte lagi dengan saran Andy
5. Revisi utama:

  • kesalahan yang ditekan dengan @ alih-alih berubah libxml_use_internal_errors
  • digunakan implode(0,file(""))alih-alih file_get_contents("")(2 byte)
  • memindahkan $xdefinisi di dalamif
  • Menggunakan throw 0alih-alih benar-benar melempar pengecualian (ini membuat crash program)
  • dengan @saya sekarang bisa menghilangkan comicLinkganti.


Percobaan pertama saya bermain golf.

DOMDocument istirahat ketika menemukan comicLinks dobule ID jadi saya harus menghapus ini. Mungkin ada cara yang lebih baik untuk melakukan itu.

Gangguan saat mencoba mendapatkan no. 859;)

<?php if(($x=$argv[1])==859)throw 0;$a=new DOMDocument;$b=@$a->loadHTML(implode(0,file("http://xkcd.com/$x")));echo $a->getElementsByTagName('img')->item(1)->getAttribute('title');
Ezenhis
sumber
2
Selamat datang di PPCG! Saya pikir Anda dapat menghapus tes apakah $x==404karena kode lain akan gagal pada respons 404 ... Anda juga dapat mengganti throw new Exceptiondengan diepanggilan dan menghapus tanda kurung di sekitar throw new Exception("")/ diekarena hanya satu pernyataan
Roman Gräf
1
Terima kasih! Saya tidak yakin apakah mati () akan dianggap sebagai "melempar kesalahan";)
Ezenhis
1
Gunakan "1" sebagai ganti 'true' di libxml_use_internal_errors. Anda mungkin dapat meneruskan 0 ke Pengecualian dan menyimpan satu ekuivalen kutipan. Menutup?> Harus opsional.
Kevin_Kinsey
Variabel diinterpolasi di dalam tanda kutip ganda, sehingga "http://xkcd.com/".$xdapat "http://xkcd.com/$x"menghemat satu byte :)
Andy
BTW, +1 untuk menggunakan teknik parsing yang "tepat" (XML parser) sebagai lawan dari hack regex jelek saya;)
Kevin_Kinsey
5

Python + xkcd , 54 byte

import xkcd
lambda n:xkcd.getComic(*{n}-{859}).altText

Verifikasi

>>> import sys
>>> sys.tracebacklimit = 0
>>>
>>> import xkcd
>>> f = lambda n:xkcd.getComic(*{n}-{859}).altText
>>>
>>> print f(149)
Proper User Policy apparently means Simon Says.
>>>
>>> f(404)
urllib2.HTTPError: HTTP Error 404: Not Found
>>>
>>> f(859)
TypeError: getComic() takes at least 1 argument (0 given)
Dennis
sumber
Saya baru saja memperhatikan ini. Golf yang bagus!
Beta Decay
5

Python telah menang, tetapi terlepas dari ...

bash + curl + sed; 88 ~ 91 heh byte

printf "$(curl -s https://xkcd.com/2048/info.0.json|sed 's/.*"alt": "//;s/", "img":.*//')\n"

Yay untuk penguraian JSON regex!

EDIT NoLongerBreathedIn memperhatikan (648 hari ke depan!) Bahwa ini gagal pada posting 2048 karena tak terduga \"dalam entri JSON itu. Regex telah diperbarui di atas; dulu sed 's/.*alt": "\([^"]\+\).*/\1/').

The printfwrapper rapi menangani fakta bahwa karakter Unicode diwakili dalam \unnnnnotasi:

$ printf "$(curl -s https://xkcd.com/1538/info.0.json | sed 's/.*"alt": "//;s/", "img":.*//')\n"
To me, trying to understand song lyrics feels like when I see text in a dream but it𝔰 hอᵣd t₀ ᵣeₐd aกd 𝒾 canٖt fཱྀcu༧༦࿐༄

 

Ini gagal dengan pos 404 dan 859:

404

$ printf "$(curl -s https://xkcd.com/404/info.0.json | sed 's/.*alt": "\([^"]\+\).*/\1/')\n"
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

859

$ printf "$(curl -s https://xkcd.com/859/info.0.json | sed 's/.*alt": "\([^"]\+\).*/\1/')\n"
Brains aside, I wonder how many poorly-written xkcd.com-parsing scripts will break on this title (or ;;\n$

Di $akhir output adalah prompt saya, dan \nlangsung dicetak sebelum benar-benar bagian dari string printf.

Saya sengaja menggunakan printfkarena akan mengurai Unicode dan jatuh sangat pada posting khusus ini.

i336_
sumber
Juga muntah di 2048. Saya pikir itu muntah di tanda kutip ganda?
NoLongerBreathed Pada
Tangkapan bagus. Pos diperbarui. Melihat sedsedikit, Anda dapat melihatnya sedang mencari alt": "lalu membaca sampai menemukan a ". Waduh, rupanya ... (Saya ingin tahu berapa banyak dari solusi ini akan gagal dalam unit test dari e̲͕̲̪v̲̺̗̱̬er̶͎y̦ ͖̙̝̦s҉̟̜i͓͜n̡g̸l͎̠̹̪͈͉͚͟e̩͙̙̣̲͕͘ ̴͎͉̳̮a̢͕l̯̦̮̥̺̱̤t̕ ͕̮̪̙̬̲̪͘t̰͙̘̪̼ͅex̺͕͍͔̠̮ͅt̪͔̀?: P)
i336_
4

Python 2 , 115 106 byte

-8 Bytes berkat Ovs. -1 byte terima kasih kepada Jonathan Allan.

Hanya berpikir saya akan meletakkan jawaban perpustakaan standar di luar sana.

lambda n:[json.load(urllib.urlopen('http://xkcd.com/%d/info.0.json'%n))['alt']][n==859]
import urllib,json
benar-benar manusiawi
sumber
1
lambda n:[json.load(urllib.urlopen('https://xkcd.com/%d/info.0.json'%n))['alt']][n==859]untuk -8 byte.
Ov
1
Harus bekerja dengan http://terlalu menghemat satu byte.
Jonathan Allan
4

Bash + curl + jq: 73 66 byte

Jawaban terpendek yang tidak menggunakan pustaka spesifik xkcd. jq adalah alat untuk memanipulasi objek json di shell, dan dilengkapi dengan bahasa parsing untuk melakukan itu.

curl -Ls xkcd.com/$1/info.0.json|jq -r 'if.num==859then.num.a else.alt end'

curl -Ls xkcd.com/$1/info.0.json|jq -r '(.num!=859//.[9]|not)//.alt'

Ekspansi di bawah ini:

curl -Ls - Permintaan, tetapi jangan ragu untuk mengarahkan ulang (dalam hal ini ke situs https) dan tidak memberikan hasil yang tidak terkait.

xkcd.com/$1/info.0.json - Tanpa malu dicuri dari jawaban lain.

|jq -r- Jalankan jqdalam mode "output mentah" pada perintah berikut.

if .num == 859 then .num.a # This fails because you can't get the key 'a' from a property that's an integer else .alt # And this pulls out the 'alt' key from our object. end

Sekarang skrip telah bekerja kembali untuk menggunakan //yang setara dengan a or bdi python, dan kami menggunakan a |notuntuk membuat nilai benar dianggap salah, sehingga yang kedua //dapat mencetak.alt

Aviator45003
sumber
2

JavaScript (ES6), 177 175 byte

p=(x)=>{eval(`console.log("${x.alt}")`)};f=(y)=>{var d=document,e=d.createElement("script");e.src=`//dynamic.xkcd.com/api-0/jsonp/comic/${y}?callback=p`;d.body.appendChild(e)}}

Rekatkan ini ke konsol browser Anda, kemudian jalankan f(859)atau f(404)lain-lain - keduanya harus error di konsol, meskipun tidak diberi kode keras, yang lain ditampilkan.

Posting pertama sebentar, maaf jika tidak memenuhi aturan ...!

James Thorpe
sumber
Gunakan x=>sebagai ganti (x)=>.
user75200
2

PHP, 160 byte

<? preg_match_all('/(tle=\")(.+)(\")\sa/',join(0,file('http://xkcd.com/'.$argv[1])),$a);echo(strstr($c=$a[2][0],'Brains asid'))?$b:html_entity_decode($c,3);
Kevin_Kinsey
sumber
Tunggu ... ini bukan spec. Memperbaiki ...
Kevin_Kinsey
Tetap. Harus menambahkan sekitar 50 byte ... :(
Kevin_Kinsey
1
Anda dapat menghapus 7 karakter menghapus gema dan memindahkan $ c assign di dalam substr
Einacio
1
@BetaDecay karena tidak memeriksa nomor input memberikan poin tambahan
Einacio
1
@ BetaDecay yah, skrip yang tergantung pada konten kelihatannya ditulis dengan buruk untuk saya. Judul lain yang dimulai seperti itu akan mematahkannya. Kevin_Kinsey Anda dapat mengganti ENT_QUOTES dengan nilainya = 3
Einacio
1

Perl, 129 167 byte

use LWP::Simple;use HTML::Entities;print decode_entities($1)if(get("http://www.xkcd.com/$ARGV[0]")=~m/text: ([^<]*)\}\}<\/div>/)

EDIT: Jiwa itu sebenarnya

use LWP::Simple;use HTML::Entities;$x=$ARGV[0];if($x==404||$x==859){die}else{print decode_entities($1)if(get("http://www.xkcd.com/$x")=~m/text: ([^<]*)\}\}<\/div>/)}

Impor dekode HTML dan akses HTTP, lalu cetak grup yang cocok dengan (...) di

{{Title text: (...)}}</div>

(hemat sedikit dengan menghilangkan {{Title dari kueri)

Untuk 404 dan 859, kematian.

archaephyrryx
sumber
Apa yang Anda maksud dengan "menangani dengan benar 859"?
Beta Decay
@BetaDecay Mencetak teks-alt yang sebenarnya
archaephyrryx
1
the program must throw an error when given the numbers 859 or 404
Beta Decay
Apa yang dimaksud dengan "melempar kesalahan"?
archaephyrryx
Nvm diecukup pendek
archaephyrryx
1

BASH, 111 108 byte

a = $ (cat) curl -s https://xkcd.com/ $ a / | grep -oP '(? <= Teks judul:) ([^}}] *)' [$ a = 404] && echo "$ a tidak ditemukan"

a=#;curl -s https://xkcd.com/$a/ |grep -oP '(?<=Title text:)([^}}]*)';[ $a = 404 ] && echo "$a not found"


Untuk Jalankan:
ubah # ke nomor komik. Jalankan dari baris perintah.

Terima kasih @Ale atas sarannya!

Silentziler
sumber
Mengapa membaca dari input standar menggunakan cat daripada hanya menggunakan $ 1 dari baris perintah? Ini akan menghemat beberapa byte ...
Ale
1

Javascript (ES6), 118 96 94 byte

f=n=>fetch(`//xkcd.com/${n}/info.0.json`).then(x=>x.json()).then(y=>eval(`alert('${y.alt}')`))

Anda dapat menempelkannya di konsol browser dan menjalankannya f(123). Tetapi lakukan pada halaman yang sudah ada di xkcd.com atau Anda akan melihat kesalahan CORS.

Untuk 404, gagal dengan:

Tidak tertangkap (dalam janji) Sintaksis: Token yang tidak terduga <di JSON pada posisi 0

Untuk 859, gagal dengan:

Tidak tertangkap (dalam janji) Sintaksis: hilang) setelah daftar argumen

Pembaruan: versi terbaru dengan benar memeriksa teks alternatif alih-alih memeriksa hanya 859 dan mencukur 2 byte lainnya.

Christiaan Westerbeek
sumber
Sayangnya, ini gagal pada titletext yang berisi apostrof (mis. 1084).
ETHproduk