Zbuduj wadliwą przeglądarkę XKCD


75

Wyzwanie

Biorąc pod uwagę numer komiksu XKCD, wypisz tekst tytułowy tego komiksu (tekst najechania myszą).

Jednak program musi zgłosić błąd po podaniu liczb 859lub 404.

Zasady

Podana liczba będzie zawsze istniejącym komiksem (z wyjątkiem 404).

Twój program nie może zgłaszać błędów dla innych liczb niż 859lub 404.

Dla porównania, komiks 404nie istnieje i 859jest:

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

Skracacze adresów URL są niedozwolone. Możesz użyć Internetu, aby uzyskać tytuł.

Przykłady

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.

Hojność

Przyznam nagrodę za najkrótszą odpowiedź, która nie powiedzie się w komiksie 859, ponieważ jest źle napisany zamiast sprawdzania numeru.

Twój program może się łamać na innych tekstach alternatywnych (takich jak 744), pod warunkiem, że mają niepasujące nawiasy, cudzysłowy itp.

Zwycięski

Najkrótszy kod w bajtach wygrywa.


2
Ponieważ istnieją inne komiksy z łamanymi skryptami tekstami alternatywnymi (patrz 744 ), czy jest w porządku, jeśli program też się na nich psuje?
totalnie ludzki,

8
@totallyhuman Powinieneś dodać do tego nieco ostrzeżenie NSFW: P
HyperNeutrino

11
Sprzeczność w wyzwaniu: „nie wolno rzucać błędem dla żadnych innych liczb niż 859lub 404” i „może złamać inne teksty alternatywne”.
aschepler

3
@aschepler Ten ostatni jest tylko dla nagrody
Beta Decay

4
@Kzqai Dobre pytanie, ale myślę, że możesz nie doceniać, ile ruchu jest zaangażowane w DDOS, a także ile ruchu już ma xkcd.com. Nie spodziewałbym się, że ruch generowany z odpowiedzi tutaj będzie znaczący w porównaniu do któregokolwiek z nich.
trichoplax

Odpowiedzi:


107

Python 2.7 + xkcd , 55 bajtów

xkcd to pakiet Pythona innej firmy. W Pythonie jest pakiet na wszystko !

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

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

Dla 859: IndexError: list index out of range


89
Pakiet został napisany przed tym wyzwaniem i nie został napisany specjalnie dla tego wyzwania, po prostu jest bardzo odpowiedni.
Draco18s

4
Wow, Python stał się bardziej atrakcyjny!
Nat


6
Przypadkowo, pyton rzeczywiście wspierać import„ing antigravity.
Yet Another User

39
Czy Python właśnie Mathematica to wyzwanie?
Arcturus,

22

Python 2 + Requests , 104 102 95 94 bajtów

-2 bajty dzięki Erikowi Outgolfer. -1 bajt dzięki Jonathan Allan.

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

Obowiązkowy:

import antigravity

Źle napisany skrypt, 98 bajtów

Tak więc pisanie kiepskich skryptów jest naprawdę trudne do umyślnego ... To również psuje inne komiksy, ponieważ zawierają cytaty, nie jestem pewien, czy to w porządku.

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

4
Myślę, że możesz to usunąć ,a.
Erik the Outgolfer

1
Możesz zmienić n in[404,859]na n==859, ponieważ i tak dekoder JSON zawiedzie 404.
musicman523

7
... http://myślę, że tutaj też można go użyć.
Jonathan Allan

1
jak faktycznie uruchamiasz to z parametrem? Jak prowadzisz bezimienną lambdę?
MrZander

1
@MrZander Pierwszy wiersz to anonimowa lambda, którą można przypisać do zmiennej, która ma być uruchomiona. Na przykład oba drukują f = lambda n: n * 2; print f(2)lub (lambda n: n * 2)(2)wydrukują 4.
całkowicie ludzki

18

Python 2 + xkcd, 82 bajty

Źle napisany skrypt

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

Dołącza i zastępuje ''', które, o ile tekst nie zawiera ''', nie będą łamane, nawet w przypadku innych znaków cudzysłowu. To znaczy, z wyjątkiem sytuacji, gdy tekst zawiera ;;, który zostaje zastąpiony '''(eliminujący re). Dotyczy to tylko 859i dlatego ten kod się zrywa 859. : P

Ponadto, nigdy nie należy evallosowo wybierać treści internetowych, ponieważ gdyby tak się xkcd.getComic(n).altTextstało '''+__import__('os').system('rm -rf / --no-preserve-root')+''', spowodowałoby to wiele złych rzeczy. Mianowicie, usunąłby wszystko, co jest dostępne dla non-sudo na komputerze, chyba że uruchamiasz programy codegolf w sudo (również niezalecane): P


1
Źle napisany i nie spełnia tego warunku testowego 859? Przypuszczam, że ktoś dostanie nagrodę ...
Pan Xcoder

12
Ach, żądza odkrywania losowych treści z Internetu - brawo! : P
Luke Briggs

@LukeBriggs Teoretycznie powinno to być bezpieczne ... Mam na myśli, że mój komputer nie wybuchł ( jeszcze ), więc powinno być dobrze, prawda? : P Ale alternatywnie możesz użyć __import__('ast').literal_evalzamiast, evaljeśli naprawdę chcesz: P
HyperNeutrino

Czy psuje się na 744?
Draco18s,

@ Draco18s Nie powinno tak być, ponieważ potrójne cytaty nie dbają o niedopasowane cytaty i nie ma ;;.
HyperNeutrino,

11

Wolfram Language / Mathematica, 118 117 bajtów

zapisano bajt dzięki numeryce

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

Wyjaśnienie:

Użyj, StringTemplateaby utworzyć adres URL na podstawie danych wejściowych.

Import[..., "RawJSON"]importuje obiekt JSON i analizuje go w pliku Assocation.

Wybierz wartość dla klucza "alt".

Weź ten wynik i spróbuj zinterpretować ciąg jako HTML ( Import[#,"HTML"]). Jeśli to nie zmieni niczego, wynik przechodzi, jeśli się zwraca $Failed. Łapie to 859, ponieważ

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

prowadzi do:

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

404 zawodzi, ponieważ

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

powoduje w $Failed.


Jakiej wersji używasz? Wchodzę The Import element "RawJSON" is not present when importing as JSONna 10.0.1.
Julian Wolf

@ totalniehuman Cóż, prawdopodobnie nie trzeba sprawdzać 859. (Zobacz warunek nagrody w pytaniu)
Beta Decay

@JulianWolf Używam 11.1.0. Myślę, że wsparcie „RawJSON” zostało dodane w 10.2.
chuy

4
@totallyhuman Nie wykonuje jawnej kontroli, ale o to ImportString[#,"HTML"]właśnie chodzi.
chuy

1
@numbermaniac Rzeczywiście mogę. Nie mogę uwierzyć, że to przegapiłem, dzięki!
chuy

8

Java 8, 255 176 bajtów

Dzięki @ OlivierGrégoire za to, że poczułam się jak idiotka i 79 bajtów wolnego. ;)

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

To wydaje się zbyt ciężkie ... Wciąż ciężkie, ale „w porządku” dla java…

Wyjaśnienie:

  • i->{...} Lambda, która działa jak String <name>(int i) throws Exception
  • new java.util.Scanner(...).setDelimiter("\\a").next() przeczytaj wszystko z podanego InputStream
    • new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream()tworzy to InputStreamodwołanie, którego treść odpowiedzi http://xkcd.com/{comic_id}/info.0.jsonjest stroną informacyjną żądanego komiksu
    • replaceFirst(".*\"alt\": \"","").replaceFirst("\".*","") Usuwa wszystko oprócz tekstu alternatywnego (do pierwszego podwójnego cudzysłowu)
  • domniemany zwrot

Alternatywne krótsze podejście, 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")

To nie jest moje rozwiązanie, więc nie chcę tego publikować jako pierwszego. Wszystkie kredyty należą do @ OlivierGrégoire.


1
Brakuje Twojego importu! . Poza tym prawie nie ma próby gry w golfa na tę odpowiedź ...
Olivier Grégoire

Dodany. Nieco poniżej 2 ^ 8. Przynajmniej rozmiar mojego programu mieści się w jednym bajcie :)
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 bajtów, uważaj na postacie z komentarza SO) A ja ledwo grałem tutaj w golfa.
Olivier Grégoire

O! Myślałem, że Scanner#useDelimiterpowraca nieważne ... Lepiej przeczytaj dokumenty następnym razem;)
Roman Gräf

1
Zauważyłem, że możesz stworzyć własną Functionklasę, która pozwoli ci wprowadzić wyjątek. Dzisiaj nie jest mój dzień.
Roman Gräf

7

PHP, 89 86 85 bajtów

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

Zwraca null dla 404 i 859

Zapisz jako xkcd.php i uruchom z numerem komiksu ...

$ php xkcd.php 386

użyj $argnzamiast $argv[1], _zamiastNULL
Jörg Hülsermann

@ JörgHülsermann Thanks! Nie wiedziałem o _. $ argn nie wydaje się jednak działać.
Jared Mellentine

php.net/manual/en/features.commandline.options.php $argn jest dostępny, jeśli uruchamiasz PHP z wiersza poleceń z opcją -Rlub-F
Jörg Hülsermann

_nie jest równoważne z NULLPHP. Ten skrypt zgłasza błąd dotyczący _niezdefiniowanej stałej.
Andy

@Andy Jeśli powiadomienie nie jest dozwolone, ""jest lepszą alternatywą, ponieważ NULLJared tutaj jest przykładem dla $argn codegolf.stackexchange.com/questions/114146/…
Jörg Hülsermann

5

PHP 5.3, 280 268 262 261 180 bajtów


1. Zaoszczędzono 11 dzięki niektórym sugestiom Romana Gräfa
2. Zaoszczędziłem 1 bajt, używając łącza http zamiast https
3. Zaoszczędziłem kolejne 6 bajtów dzięki Kevin_Kinsay
4. Zaoszczędziłem kolejny 1 bajt dzięki sugestii Andy'ego 5. Ważna
zmiana:

  • pomijane błędy za pomocą @ zamiast zmiany libxml_use_internal_errors
  • użyte implode(0,file(""))zamiast file_get_contents("")(2 bajty)
  • przeniesiono $xdefinicję doif
  • Używanie throw 0zamiast faktycznego zgłaszania wyjątku (powoduje awarię programu)
  • z @I teraz mogę pominąć comicLinkzamianę.


Moja pierwsza próba gry w golfa.

DOMDocument pęka, gdy napotyka comicLinks z identyfikatorem dobule, więc musiałem je usunąć. Prawdopodobnie jest to lepszy sposób.

Awarie podczas próby uzyskania nie. 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
Witamy w PPCG! Myślę, że można usunąć test, czy $x==404dlatego, że inny kod nie powiedzie się od odpowiedzi 404 ... Ponadto można zastąpić throw new Exceptionprzez dierozmowy i usuń nawiasy wokół throw new Exception("")/ diebo jest tylko jedno stwierdzenie
Roman Gräf

1
Dzięki! Nie byłem pewien, czy die () liczy się jako „wyrzucenie błędu”;)
Ezenhis

1
Użyj „1” zamiast „true” na libxml_use_internal_errors. Prawdopodobnie możesz przekazać 0 do wyjątku i zapisać jeden ekwiwalent wyceny. Zamknięcie?> Powinno być opcjonalne.
Kevin_Kinsey

Zmienne są interpolowane w podwójnych cudzysłowach, więc "http://xkcd.com/".$xmożna "http://xkcd.com/$x"zapisać jeden bajt :)
Andy

BTW, +1 za użycie „właściwej” techniki parsowania (parser XML) w przeciwieństwie do mojego brzydkiego hackowania wyrażenia regularnego;)
Kevin_Kinsey

5

Python + xkcd , 54 bajty

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

Weryfikacja

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

Właśnie to zauważyłem. Niezły golf!
Beta Decay

5

Python już wygrał, ale niezależnie od ...

bash + curl + sed; 88 ~ 91 heh bajtów

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

Tak, parsowanie wyrażenia regularnego JSON!

EDYCJA NoLongerBreathedIn zauważyła (648 dni w przyszłość!), Że nie powiodło się to po 2048 roku z powodu nieoczekiwanego \"JSON tego wpisu. Wyrażenie regularne zostało zaktualizowane powyżej; kiedyś tak było sed 's/.*alt": "\([^"]\+\).*/\1/').

printfWrapper zgrabnie radzi sobie fakt, że znaki Unicode są reprezentowane w \unnnnnotacji:

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

 

Nie udaje się to z postami 404 i 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$

Na $końcu danych wyjściowych znajduje się mój monit i dosłownie wydrukowany \nbezpośrednio przed umieszczeniem go w łańcuchu printf.

Celowo użyłem, printfponieważ analizowałby Unicode i strasznie przewracał się w tym konkretnym poście.


Również barfs w 2048 roku. Myślę, że to barfs w podwójnych cudzysłowach?
NoLongerBreathedIn

Dobry chwyt. Opublikowana aktualizacja. Patrząc na sedkawałek, widać, że szukał, alt": "a następnie czytał, aż znalazł ". Woops, najwyraźniej ... (Zastanawiam się, ile z tych rozwiązań nie przejdzie testu jednostkowego e̲͕̲̪v̲̺̗̱̬er̶͎y̦ ͖̙̝̦s҉̟̜i͓͜n̡g̸l͎̠̹̪͈͉͚͟e̩͙̙̣̲͕͘ ̴͎͉̳̮a̢͕l̯̦̮̥̺̱̤t̕ ͕̮̪̙̬̲̪͘t̰͙̘̪̼ͅex̺͕͍͔̠̮ͅt̪͔̀ ?: P)
i336_

4

Python 2 , 115 106 bajtów

-8 bajtów dzięki ovs. -1 bajt dzięki Jonathan Allan.

Pomyślałem, że opublikuję tam standardową odpowiedź z biblioteki.

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]dla -8 bajtów.
ovs

1
Powinien działać ze http://zbyt oszczędnym bajtem.
Jonathan Allan

4

Bash + curl + jq: 73 66 bajtów

Najkrótsza odpowiedź, która nie korzysta z biblioteki specyficznej dla xkcd. jq jest narzędziem do manipulowania obiektami json w powłoce i jest do tego wyposażony w parsujący język.

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'

Rozszerzenie poniżej:

curl -Ls - Zapytanie, ale możesz przekierować (w tym przypadku na stronę https) i nie dawać niepowiązanych wyników.

xkcd.com/$1/info.0.json - Bezwstydnie skradziony z innej odpowiedzi.

|jq -r- Uruchom jqw trybie „surowego wyjścia” przy użyciu następującego polecenia.

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

Teraz skrypt został przerobiony do użycia, //co jest odpowiednikiem a or bw pythonie, i używamy a, |notaby każda prawdziwa wartość była uważana za fałszywą, aby druga //mogła wydrukować.alt


2

JavaScript (ES6), 177 175 bajtów

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

Wkleić do konsoli przeglądarki, a następnie wykonać f(859)lub f(404)etc - te dwa powinny błąd w konsoli, mimo że nie jest zakodowana, inni wyświetlić.

Pierwszy post od jakiegoś czasu, przepraszam, jeśli nie do końca spełnia zasady ...!


Użyj x=>zamiast (x)=>.
user75200

2

PHP, 160 bajtów

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

Poczekaj ... to nie jest specyfikacja. Naprawianie ...
Kevin_Kinsey

Naprawiony. Musiałem jednak dodać około 50 bajtów ... :(
Kevin_Kinsey

1
możesz usunąć 7 znaków usuwając echo i przenosząc przypisanie $ c wewnątrz
substratu

1
@BetaDecay, ponieważ nie sprawdzenie numeru wejściowego daje dodatkowe punkty
Einacio

1
@BetaDecay dobrze, skrypt, który zależy od treści, wygląda na źle napisany do mnie. Każdy inny tytuł zaczynający się w ten sposób złamałby go. Kevin_Kinsey możesz zastąpić ENT_QUOTES jego wartością = 3
Einacio

1

Perl, 129 167 bajtów

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

EDYCJA: Psyche to faktycznie

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

Zaimportuj dekodowanie HTML i dostęp do HTTP, a następnie wydrukuj grupę pasującą do (...) w

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

(trochę oszczędzając, pomijając {{Title zapytanie)

Za 404 i 859 śmierć.


Co rozumiesz przez „prawidłowo obsługuje 859”?
Beta Decay

@BetaDecay Drukuje rzeczywisty tekst
alternatywny

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

Co to jest zdefiniowane jako „wyrzucić błąd”?
archaephyrryx

Nvm diejest wystarczająco krótki
archaephyrryx

1

BASH, 111 108 bajtów

a = $ (cat) curl -s https://xkcd.com/ $ a / | grep -oP '(? <= Tekst tytułu:) ([^}}] *)' [$ a = 404] && echo „Nie znaleziono $”

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


Aby uruchomić:
zmień # na liczbę komiksów. Uruchom z wiersza poleceń.

Dzięki @Ale za sugestię!


Po co czytać ze standardowego wejścia za pomocą cat zamiast po prostu 1 $ z wiersza poleceń? Zaoszczędziłoby to trochę bajtów ...
Ale

1

JavaScript (ES6), 118 96 94 bajty

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

Możesz wkleić to w konsoli przeglądarki i uruchomić f(123). Ale zrób to na stronie, która jest już na xkcd.com, w przeciwnym razie zobaczysz błąd CORS.

W przypadku 404 nie działa z:

Nieprzechwycony (w obietnicy) Składnia Błąd: Nieoczekiwany token <w JSON na pozycji 0

W przypadku 859 nie działa z:

Nieprzechwycony (w obietnicy) Składnia Błąd: brak) po liście argumentów

Aktualizacja: ostatnia wersja poprawnie sprawdza tekst alternatywny zamiast sprawdzania tylko 859 i goli kolejne 2 bajty.


Niestety nie udaje się to w przypadku dowolnego tekstu tytułowego zawierającego apostrof (np. 1084).
ETHprodukcje
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.