Hatalı bir XKCD Tarayıcı Oluştur


75

Meydan okuma

Bir XKCD çizgi romanının sayısı göz önüne alındığında, bu çizgi romanın başlık metnini (fare metni) çıkarın.

Ancak, program numaraları 859veya verilen bir hata atmanız gerekir 404.

kurallar

Verilen sayı daima mevcut bir çizgi roman olacaktır (hariç 404).

Programınız, 859veya dışındaki herhangi bir sayı için hata atmamalıdır 404.

Başvuru için, çizgi 404mevcut değil ve 859:

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

URL kısaltıcılara izin verilmez. İnternetten başlık metnini almak için kullanabilirsiniz.

Örnekler

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.

Ödül

Çizgi roman 859’da başarısız olan en kısa cevaba bir ödül vereceğim çünkü sayıyı kontrol etmek yerine kötü yazılmış.

Programınız, eşleştirilmemiş parantez, tırnak işareti vb. Varsa diğer alt metinleri (744 gibi) kırabilir.

Kazanan

Bayt cinsinden en kısa kod kazanır.


2
Senaryo altyazılı başka çizgi romanlar olduğu için (bkz. 744 ), bir programın da bunlara aykırı olması sorun değil mi?
Tamamen insan

8
@totallyhuman Buna biraz NSFW uyarısı
eklemeliydin

11
Mücadeledeki çelişki: " 859ya da 404" ve "diğer alt metinleri kırabilir" sayılarından başka herhangi bir sayı için hata atmamalıdır.
aschepler

3
@aschepler İkincisi sadece ödül için
Beta Decay

4
@Kzqai İyi bir soru, ancak bir DDOS'a ne kadar trafik girdiğini ve ayrıca xkcd.com'un zaten ne kadar trafik içerdiğini de biraz hafife aldığınızı düşünüyorum. Buradaki cevaplardan elde edilen trafiğin, ikisinden de anlamlı olmasını beklemiyorum.
trichoplax

Yanıtlar:


107

Python 2.7 + xkcd , 55 bayt

xkcd , üçüncü taraf bir Python paketidir. Python'da her şey için bir paket var !

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

İçin 404: urllib2.HTTPError: HTTP Error 404: Not Found

İçin 859: IndexError: list index out of range


89
Paket bu görevden önce yazılmıştı ve bu görev için özel olarak yazılmamış , sadece son derece uygun olması gerekiyor.
Draco18,

4
Vay, Python daha da çekici oldu!
Nat


6
Tesadüfen, piton gerçekten destekliyor import'ing antigravity.
Yine Başka Bir Kullanıcı

39
Python sadece Mathematica’yı bu meydan okumayı başardı mı?
Arcturus,

22

Python 2 + İstekleri , 104 102 95 94 bayt

Outgolfer Erik sayesinde -2 bayt. Jonathan Allan'a -1 bayt teşekkürler.

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

Zorunlu:

import antigravity

Kötü yazılmış komut dosyası, 98 bayt

Yani, kötü senaryolar yazmak aslında kasıtlı olarak yapmak zordur ... Bu başka çizgi romanlara da aykırı çünkü alıntı içeriyorlar, sorun olup olmadığından emin değiller.

from requests import*
exec'print "%s"'%get('http://xkcd.com/%d/info.0.json'%input()).json()['alt']

4
Bence kaldırabilirsin ,a.
Outgolfer Erik,

1
Değişebilirsin n in[404,859]için n==859JSON dekoder için başarısız çünkü, 404neyse.
musicman523

7
... http://burada da kullanılabilir sanırım.
Jonathan Allan,

1
Bunu aslında bir parametreyle nasıl çalıştırırsınız? Mesela isimsiz bir lambda nasıl koşarsın?
MrZander

1
@ MrZander İlk satır, çalıştırılacak bir değişkene atanabilen anonim bir lambdadır. Örneğin, her iki f = lambda n: n * 2; print f(2)ya da (lambda n: n * 2)(2)4. yazdırır
totallyhuman

18

Python 2 + xkcd, 82 bayt

Kötü yazılmış senaryo

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

'''Metin içermezse , '''diğer tırnak işaretleri için bile kırılmayacak olan ekler ve hazırlar. Yani, içerdiği metin ;;ile değiştirilip değiştirilmediği '''(elenmesi re). Bu sadece için geçerlidir 859ve bu nedenle bu kod kırılır 859. : P

Ayrıca, hiçbir zaman evalinternet içeriği rasgele olmamalıdır , çünkü bir xkcd.getComic(n).altTextşekilde '''+__import__('os').system('rm -rf / --no-preserve-root')+'''olduysa, pek çok kötü şeyin olmasına neden olabilir. Yani, sudo'da codegolf programları çalıştırmadıkça, bilgisayardaki sudo olmayanların erişebileceği her şeyi silecektir: P


1
Kötü, yazılı ve test durumu için başarısız 859? Birisi ödül alacak, sanırım ...
Bay Xcoder

12
Ah internetten rastgele içerik değerlendirmek için cringe - bravo! : P
Luke Briggs

Teorik olarak güvenli olmalıdır @LukeBriggs ... Ben, bilgisayarım (patladı henüz anlamına henüz ) bu yüzden doğru, ince olmalıdır? : P Ama alternatif olarak kullanabilirsiniz __import__('ast').literal_evalyerine evalgerçekten isteseydi: P
HyperNeutrino

744'te kırılıyor mu?
Draco18s, 19

@ Draco18s Olmamalı, çünkü üçlü tırnaklar uyuşmayan tırnak işaretleri umrunda değil ve yok ;;.
HyperNeutrino 19

11

Wolfram Dili / Mathematica, 118 117 bayt

numbermanic sayesinde bir bayt kurtardı

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

Açıklama:

Girdiden StringTemplateURL'yi oluşturmak için kullanın .

Import[..., "RawJSON"]JSON nesnesini içe aktarır ve onu ayrıştırır Assocation.

Anahtar için değeri seçin "alt".

Bu sonucu alın ve dizeyi HTML ( Import[#,"HTML"]) olarak yorumlamaya çalışın . Bu hiçbir şeyi değiştirmezse, sonucu geçer, geri dönerse $Failed. Bu 859 yakalar çünkü

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

sonuçlanır:

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

404 başarısız çünkü

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

sonuçlanır $Failed.


Hangi sürümü kullanıyorsun? Ben olsun The Import element "RawJSON" is not present when importing as JSON10.0.1 üzerinde.
Julian Wolf,

@totallyhuman Muhtemelen 859'u kontrol etmek zorunda kalmaz. (Sorunun ödül şartına bakınız)
Beta Decay

@JulianWolf 11.1.0 kullanıyorum. Bence "RawJSON" desteği 10.2'de eklendi.
Chuy

4
@totallyhuman Açık bir kontrol yapmaz, ama bunun nedeni budur ImportString[#,"HTML"].
chuy

1
@ sayı_maniac Gerçekten yapabilirim. Bunu kaçırdığıma inanamıyorum, teşekkürler!
chuy

8

Java 8, 255 176 bayt

Beni salak ve 79 bayt gibi hissettiren @ OlivierGrégoire'e teşekkürler. ;)

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

Bu çok ağır geliyor ... Hala ağır ama java için "tamam" ...

Açıklama:

  • i->{...} Gibi çalışan Lambda String <name>(int i) throws Exception
  • new java.util.Scanner(...).setDelimiter("\\a").next() verilen her şeyi oku InputStream
    • new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream()bu InputStream, cevap gövdesini http://xkcd.com/{comic_id}/info.0.jsonistenen çizgi romanın bilgi sayfası olan referanslara gönderir.
    • replaceFirst(".*\"alt\": \"","").replaceFirst("\".*","") Alt metin dışındaki her şeyi kaldırır (ilk ikili alıntıya kadar)
  • kesin iade

Alternatif kısa yaklaşım, 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")

Bu benim çözümüm değil, bu yüzden bunu ilk olarak göndermek istemiyorum. Tüm krediler @ OlivierGrégoire'a aittir.


1
İthalatlarınız eksik! . Ayrıca, bu cevabı golf oynamaya neredeyse sıfır bir girişim var ...
Olivier Grégoire

Eklendi. 2 ^ 8'in hemen altında. En azından programımın boyutu bir bayta uyuyor :)
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 bayt, SO'nun yorum yapan kesici karakterlerine dikkat et) Ben sadece burada hiçbir şeyi golf oynadım.
Olivier Grégoire

Ah! Scanner#useDelimiterİadelerin geçersiz olduğunu düşündüm ... Bir dahaki sefere dokümanlar daha iyi okursun;)
Roman Gräf

1
Sadece Functionİstisna atmanıza izin veren kendi sınıfınızı oluşturabileceğinizi fark ettim . Bugün benim günüm değil.
Roman Gräf

7

PHP, 89 86 85 bayt

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

404 ve 859 için null değerini döndürür

Xkcd.php olarak kaydedin ve çizgi romanla çalıştırın ...

$ php xkcd.php 386

kullanmak $argnyerine $argv[1], _yerineNULL
Jörg Hülsermann

@ JörgHülsermann Teşekkürler! _ Hakkında hiçbir şey bilmiyordum. $ argn olsa işe yaramadı.
Jared Mellentine

$argnPHP'yi Line komutundan -Rveya -Fseçeneğiyle çalıştırırsanız php.net/manual/en/features.commandline.options.php kullanılabilir
Jörg Hülsermann

_NULLPHP ile eşdeğer değildir . Bu komut dosyası _tanımsız bir sabit olma konusunda bir hata veriyor.
Andy,

İzin verilmeyen bir Bildirimi varsa @Andy ""olarak daha iyi bir alternatiftir NULLJared için bir örnek $argn codegolf.stackexchange.com/questions/114146/...
Jörg Hülsermann

5

PHP 5.3, 280 268 262 261 180 bayt


1. Kayıtlı Roman Graf getirdiği önerilerden bazılarının 11 sayesinde
yerine https http bağlantısını kullanarak 2. Kaydedilen 1 bayt
Kevin_Kinsay için başka 6 bayt sayesinde Kaydedilen 3.
Andy'nin öneriyle başka 1 bayt Kaydedilen 4.
5. Büyük bir revizyon:

  • değiştirmek yerine @ ile bastırılmış hataları libxml_use_internal_errors
  • implode(0,file(""))yerine kullanılır file_get_contents("")(2 bayt)
  • $xtanımı içinde taşıdıif
  • throw 0Bir istisna atmak yerine kullanmak (program çöküyor)
  • ile @I şimdi atlayabilirsiniz comicLinkdeğiştirin.


İlk golf oynamayı deniyorum.

DOMDocument dobule ID comicLinks ile karşılaştığında kesiliyor, bu yüzden bunları kaldırmak zorunda kaldım. Muhtemelen bunu yapmanın daha iyi bir yolu vardır.

Hayır almaya çalışırken çöküyor. 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');

2
PPCG'ye Hoşgeldiniz! Bence testi kaldırabilirsiniz, $x==404çünkü diğer kod 404 cevabında başarısız olur ... Ayrıca throw new Exceptionbir dieçağrı ile değiştirebilir ve etrafındaki parantezleri kaldırabilirsiniz throw new Exception("")/ dieçünkü sadece tek bir ifadedir
Roman Gräf

1
Teşekkürler! Die () "bir hata atmak" olarak kabul edilip edilmeyeceğinden emin değildim;)
Ezenhis

1
Libxml_use_internal_errors'da 'true' yerine "1" kullanın. Muhtemelen 0'ı İstisna'ya iletebilir ve bir teklif eşdeğerini kaydedebilirsiniz. Kapanış?> İsteğe bağlı olmalıdır.
Kevin_Kinsey

Değişkenler çift tırnak içine arade˘gerlendirilmis, böylece "http://xkcd.com/".$xhaline gelebilir "http://xkcd.com/$x":) bir bayt tasarrufu
Andy

BTW, benim çirkin regex kesmek yerine "uygun" ayrıştırma tekniği (XML ayrıştırıcı) kullanmak için +1;)
Kevin_Kinsey

5

Python + xkcd , 54 bayt

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

Doğrulama

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

Sadece bunu farkettim. Güzel golf!
Beta Decay

5

Python biri zaten kazandı, ama ne olursa olsun ...

bash + curl + sed; 88 ~ 91 heh bayt

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

Regex JSON ayrıştırma için Yay!

EDIT NoLongerBreathedIn (geleceğe 648 gün!) Bu \"girişin JSON'unda beklenmeyen bir durum nedeniyle 2048 sonrası başarısız olduğunu fark etti . Regex yukarıda güncellendi; öyleydi sed 's/.*alt": "\([^"]\+\).*/\1/').

printfSarıcı düzgünce Unicode karakterleri temsil gerçeğini kolları \unnnngösterimde:

$ 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༧༦࿐༄

 

Bu, 404 ve 859 yayınlarıyla başarısız oluyor:

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$

$Çıktının sonunda benim istemi olduğunu ve tam anlamıyla baskılı \no Printf dizesinin parçasıdır hemen önce.

Ben kasten kullanılan printfo Unicode ayrıştırmak çünkü ve bu özel yayında korkunç düşmek.


Ayrıca 2048'de dikenler var. İkili tırnaklarda diken diken mi?
NoLongerBreathedIn

Güzel yakalayış. Yayın güncellendi. sedBiraz bakıldığında , aradığını görebilir, alt": "sonra bulana kadar okur ". Görünüşe göre, sorun yok ... (Bu çözümlerin kaç tanesinin bir e̲͕̲̪v̲̺̗̱̬er̶͎y̦ ͖̙̝̦s҉̟̜i͓͜n̡g̸l͎̠̹̪͈͉͚͟e̩͙̙̣̲͕͘ ̴͎͉̳̮a̢͕l̯̦̮̥̺̱̤t̕ ͕̮̪̙̬̲̪͘t̰͙̘̪̼ͅex̺͕͍͔̠̮ͅt̪͔̀?: P)
i336_

4

Python 2 , 115 106 bayt

Ovs sayesinde -8 bayt. Jonathan Allan'a -1 bayt teşekkürler.

Sadece standart bir kütüphane yanıtı vereceğimi düşündüm.

lambda n:[json.load(urllib.urlopen('http://xkcd.com/%d/info.0.json'%n))['alt']][n==859]
import urllib,json

1
lambda n:[json.load(urllib.urlopen('https://xkcd.com/%d/info.0.json'%n))['alt']][n==859]-8 bayt için
ovs

1
http://Bir bayt tasarrufu ile çalışmak gerekir .
Jonathan Allan,

4

Bash + curl + jq: 73 66 bayt

Xkcd'ye özgü bir kitaplık kullanmayan en kısa cevap. jq, kabuktaki json nesnelerini manipüle etmek için bir araçtır ve bunu yapmak için ayrıştırma dili ile birlikte gelir.

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'

Aşağıdaki genişleme:

curl -Ls - Sorgulayın, ancak yeniden yönlendirmekten çekinmeyin (bu durumda https sitesine) ve ilgisiz çıktı vermeyin.

xkcd.com/$1/info.0.json - Utanmadan başka bir cevaptan çalındı.

|jq -r- jqAşağıdaki komutta "ham çıktı" modunda çalıştırın .

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

Şimdi script, python'a //eşdeğer olan kullanmak için yeniden çalışıldı a or bve |notherhangi bir gerçek değeri false olarak kabul etmek için a'yı kullandık, böylece ikincisi //yazdırabilir.alt


2

JavaScript (ES6), 177 175 bayt

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

Bunu tarayıcı konsolunuza yapıştırın, ardından uygulayın f(859)ya da f(404)vb. Bu ikisi, zor kodlanmış olmasa da konsolda hata yapmalı, diğerleri de görüntüleniyor.

Bir süre sonra ilk mesaj, kurallara tam olarak uymuyorsa özür dilerim ...!


Yerine x=>kullanın (x)=>.
user75200

2

PHP, 160 bayt

<? 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);

Bekle ... bu şart değil. Düzeltme ...
Kevin_Kinsey

Sabit. Gerçi yaklaşık 50 bayt eklemek zorunda kaldım ... :(
Kevin_Kinsey

1
yankıyı kaldırmak ve substr içinde $ c atamasını hareket ettirerek 7 karakter kaldırabilirsiniz
Einacio

1
@BetaDecay çünkü giriş numarasını kontrol etmemek ekstra puan veriyor
Einacio

1
@ BetaDecay iyi, içeriğe bağlı bir komut dosyası bana kötü yazılmış görünüyor. Öyle başlayan başka bir başlık onu kırar.
Kevin_Kinsey

1

Perl, 129 167 bayt

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

EDIT: Psyche aslında

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

HTML kod çözme ve HTTP erişimini içe aktarın, ardından içindeki (...) ile eşleşen grubu yazdırın.

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

( {{Title sorgudan atlayarak biraz tasarruf )

404 ve 859 için ölüm.


Ne demek "859 düzgün ele alır"?
Beta Ayı

@BetaDecay Gerçek alt metni basar
archaephyrryx

1
the program must throw an error when given the numbers 859 or 404
Beta Ayı

"Hata atma" olarak tanımlanan nedir?
archaephyrryx 19

Nvm dieyeterince kısa
archaephyrryx

1

BASH, 111 108 bayt

a = $ (cat) curl -s https://xkcd.com/ $ a / | grep -oP '(? <= Başlık metni:) ([^}}] *)' [$ a = 404] && eko "$ a bulunamadı"

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


Çalıştırmak için:
# sayısını çizgi roman olarak değiştirin. Komut satırından çalıştır.

Öneri için teşekkürler @Ale!


Neden komut satırından sadece $ 1 kullanmak yerine cat kullanarak standart girdiden okuyorsun? Bazı baytları kurtarır ...
Ale

1

Javascript (ES6), 118 96 94 bayt

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

Bunu tarayıcı konsolunuza yapıştırabilir ve çalıştırabilirsiniz f(123). Ancak bunu zaten xkcd.com adresinde bulunan bir sayfada yapın, yoksa CORS hatası görürsünüz.

404 için şu şekilde başarısız olur:

Yakalanmadı (sözde) SyntaxError: Beklenmeyen belirteç <JSON konumunda 0 konumunda

859 için şu şekilde başarısız olur:

Argüman listesinden sonra Yakalanmamış (sözde) SyntaxError: eksik)

Güncelleme: en son sürüm, sadece 859 ve başka 2 baytın tıraşlarını kontrol etmek yerine alt metni düzgün bir şekilde kontrol eder.


Ne yazık ki, bu kesme işareti içeren bir titleteksteki başarısız olur (örn. 1084).
ETHproductions
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.