Określ, czy wyzwanie jest warte odpowiedzi

21

Jestem bardzo zwyczajnym golfistą i nie widzę często postów, dopóki nie pojawią się na pasku bocznym „Hot Network Questions” na StackOverflow. Zazwyczaj spóźniam się na grę, a ponieważ jedynym językiem, który znam, jest Python, nie ma sensu odpowiadać na mnie, ponieważ jest już kilka odpowiedzi w Pythonie. Twoim zadaniem jest dowiedzieć się, czy warto mi odpowiedzieć na pytanie.

Wkład:

  • Twój kod (funkcja lub program) przyjmuje jeden parametr wejściowy i

Wydajność:

  • Wartość Prawda lub Falsey dla identyfikatora pytania i. Wyjście Prawda, jeśli pytanie ma więcej niż 5 odpowiedzi, więcej niż 3 wynik pytania i jedną lub mniej odpowiedzi w Pythonie (bez rozróżnienia między wersją).

Zasady / wyjaśnienia:

  • Format wejściowy może być dowolny rozsądny (standardowy, plik, wiersz poleceń), ale powinien zostać określony w odpowiedzi. Typy danych i początkowe / końcowe białe znaki nie mają znaczenia.
  • Załóżmy, że identyfikator pytania jest ważny dla codegolf.stackexchange.com.
  • Zignoruj ​​wymagania dotyczące konkretnych pytań. (tzn. jeśli pytanie spełnia liczbę głosów i odpowiedzi i nie ma odpowiedzi w języku Python, ponieważ jest to tylko Java, nadal daje wynik Prawda).
  • Odpowiedź kwalifikuje się jako odpowiedź w języku Python, jeśli „python” (case insenstive) występuje gdziekolwiek przed pierwszą nową linią postu.
  • To jest kod golfowy, więc wygrywa najkrótszy kod w bajtach.

Przykładowe przypadki *

id = 79082 => True
id = 78591 => False (less than 5 answers, also hella hard)
id = 78410 => True
id = 76428 => False (greater than 1 Python answer)
id = 78298 => False (not high enough question score)

* Zweryfikowane w momencie publikacji, mogły ulec zmianie

wnnmaw
źródło
Znam też Python ...
R. Kap
Znam też głównie Pythona.
user48538
Muszę zacząć uczyć się innych języków.
R. Kap
5
@ R.Kap, to wyzwanie byłoby świetnym czasem na rozpoczęcie!
wnnmaw
2
Na to wyzwanie warto najwyraźniej odpowiedzieć.
Rɪᴋᴇʀ

Odpowiedzi:

8

05AB1E , 167 160 159 158 156 154 143 bajtów

Cholera, prawie tak długo jak normalny język ...

Bzdura ... już obecnie bije odpowiedź Ruby o 1 bajt.

Teraz dłużej niż odpowiedź Ruby, argh! .

Prawdopodobnie powinienem już teraz iść spać.

Dzięki @wnnmaw za uratowanie 1 bajtu i dzięki @R. Kap za zapisanie kolejnych 2 bajtów!

Kod:

’£Ø ˆå§¾.‡¢ as g;#.¾¿„–(g.ˆåƒÛ('·Ç://ÐÏg.´¢/q/'+•œ_#()).‚Ø())’.e©’„à="Ž»"’DU¢®…ƒŠ‡¡`99£þs\®X¡¦vy’„à="‚¬-„¹"’¡¦'>¡¦¦¬l’±¸’¢s\}rUV)O2‹X5›Y3›)P

Lub z większą czytelnością:

’£Ø ˆå§¾.‡¢ as g;#.¾¿„–(g.ˆåƒÛ('·Ç://ÐÏg.´¢/q/'+•œ_#()).‚Ø())’
 .e©
’„à="Ž»"’
 DU¢®
“ƒŠ‡“
 ¡`99£þs\®X¡¦
v
 y’„à="‚¬-„¹"’¡¦'>¡¦¦¬l’±¸’¢s\}rUV)O2‹X5›Y3›)P

Wyjaśnienie:

Przede wszystkim kompresuje się tutaj dużo tekstu, co przekłada się na stary, dobry Python. Wersja nieskompresowana to:

"import urllib.request as g
 f=g.urlopen('http://ppcg.lol/q/'+pop_#())
 #.append(f.read())"
.e©“class="answer"“¢®"useful and clear"¡`99£þs\®“class="answer"“¡¦vy“class="post-text"“¡¦'>¡¦¦¬l"python"¢s\}rUV)O2‹X5›Y3›)P

Ta część:

import urllib.request as g
stack.append(g.urlopen('http://ppcg.lol/q/'+pop_stack()).read())`

faktycznie wyskakuje wartość stosu, kopiuje ją do adresu URL i pobiera wszystkie dane HTML. Dane HTML są wypychane na stos za pomocą #.append(f.read()).

Bieżemy liczbę odpowiedzi , licząc liczbę wystąpień class="answer".

Aby policzyć liczbę głosów, po prostu podzieliliśmy dane na „użyteczne i jasne” i zachowujemy tylko wartości cyfrowe [0:99]użycia ®"useful and clear"¡`99£þ. To jest liczba pozytywnych opinii.

W końcu musimy sprawdzić każdą odpowiedź, jeśli tekst "Python"istnieje przed końcowym tekstem nagłówka. Aby uzyskać wszystkie odpowiedzi, po prostu podzieliliśmy dane class="post-text"i ponownie podzieliliśmy każdą z nich <. Usuwamy dwa pierwsze elementy, aby uzyskać część, w której wyświetlany jest język, i sprawdzamy, czy w tym ciągu znajduje się mała wersja.

Więc teraz nasz stos wygląda tak dla id = 79273:

`[6, '14', 0, 0, 0, 1, 0, 0]`
  │    │   └───────┬──────┘
  │    │           │
  │    │   is python answer?
  │    │
  │    └── number of upvotes
  │
  └─── number of answers

Można to również zobaczyć po -dwłączeniu flagi ebug w tłumaczu.

Tak więc to tylko kwestia przetwarzania danych:

rUV)O2‹X5›Y3›)P

r                # Reverse the stack
 U               # Pop the number of answers value and store into X
  V              # Pop the number of upvotes value and store into Y
   )O            # Wrap everything together and sum it all up
     2‹          # Check if smaller than 2
       X5›       # Push X and check if greater than 5
          Y3›    # Push Y and check if greater than 3
             )P  # Wrap everything into an array and take the product.
                   This results into 1 if and only if all values are 1 (and not 0).

Wykorzystuje kodowanie CP-1252 . Możesz pobrać tłumacza tutaj .

Adnan
źródło
12
Podoba mi się wersja „bardziej czytelna”; te dodatkowe łamanie linii naprawdę robi różnicę! ;)
Wildcard
@Wildcard Oni naprawdę robią różnicę;)
Erik the Outgolfer
Czy możesz zapisać bajty za pomocą ppcg.lol/q/idkompresji?
wnnmaw
@wnnmaw Dzięki, teraz jestem tylko 1 bajt od Ruby odpowiedź: p.
Adnan
1
O nie! Nie sądzę, że potrafię wyciąć wystarczającą liczbę rogów, aby zaoszczędzić 7 bajtów. Muszę znów iść naprzód ... Chyba muszę zadowolić się drugim miejscem
Value Ink
5

Python 3.5, 280 272 260 242 240 bajtów:

( Podziękowania dla Adnana za sztuczkę *związaną z użyciem operatora w porównaniach dających 2 zapisane bajty! )

def g(o):import urllib.request as u,re;R=re.findall;w=bytes.decode(u.urlopen('http://ppcg.lol/q/'+o).read());print((len(R('(?:<h[0-9]>|<p>).*python',w.lower()))<2)*(int(R('(?<="vote-count-post ">)[0-9]+',w)[0])>3)*w.count('answercell">')>5)

Wystarczająco proste. Używa wbudowanej urllibbiblioteki Pythona, aby przejść do strony pytania, a następnie używa wyrażeń regularnych, aby znaleźć liczbę głosów, liczbę odpowiedzi i liczbę konkretnych odpowiedzi w języku Python w zdekodowanym tekście zwróconym ze strony internetowej. Na koniec wartości te są porównywane z warunkami wymaganymi do zwrócenia truthywartości, a jeśli spełniają wszystkie warunki, Truesą zwracane. W przeciwnym razie Falsejest.

Jedyne, o co mogę się tutaj martwić, to to, że wyrażenia regularne dają wiele swobodnego zrozumienia pod względem liczby specyficznych odpowiedzi na python, aby zaoszczędzić bajty, więc czasami może być nieco niedokładne, chociaż prawdopodobnie jest wystarczająco dobre dla cele tego wyzwania. Jeśli jednak chcesz mieć znacznie dokładniejszy, dodałem jeden poniżej, chociaż jest on dłuższy niż powyższy. Ten pokazany poniżej ma obecnie 298 bajtów, ponieważ używa znacznie dłuższego wyrażenia regularnego - takiego, którego nie mogłem wiedzieć, ile czasu zajęło mi odkrycie - do zliczania odpowiedzi w Pythonie niż moja pierwotna funkcja ze względu na dokładność. Ten powinien działać przez około 80% do 90% wszystkich rzuconych na niego przypadków testowych.

def g(o):import urllib.request as u,re;R=re.findall;w=bytes.decode(u.urlopen('http://ppcg.lol/q/'+o).read());print(len(R('(?<=answercell">).*?(?:<h[0-9]>|<strong>)[^\n]*python[^\n]*(?=</h[0-9]>|</strong>)',w.lower()))<2and int(R('(?<="vote-count-post ">)[0-9]+',w)[0])>3and w.count('answercell">')>5)

Ale co z tymi pytaniami z wieloma stronami odpowiedzi? Żadne z powyższych nie zadziała bardzo dobrze w tej sytuacji, jeśli powiedzmy, że 1 odpowiedź na python znajduje się na pierwszej stronie, a inna na drugiej. Pozwoliłem sobie rozwiązać ten problem, tworząc kolejną wersję mojej funkcji (pokazanej poniżej), która sprawdza każdą stronę odpowiedzi, jeśli istnieje wiele odpowiedzi, pod kątem odpowiedzi w języku Python, i całkiem nieźle poradziła sobie w wielu przypadkach testowych I rzuciłem na to. Cóż, bez zbędnych ceregieli, oto nowa i zaktualizowana funkcja:

def g(o):
 import urllib.request as u,re;R=re.findall;w=bytes.decode(u.urlopen('http://ppcg.lol/q/'+o).read());t=0if len(re.findall('="go to page ([0-9]+)">',w))<1else max([int(i)for i in re.findall('="go to page ([0-9]+)">',w)])
 if t<1:print(len(R('(?<=answercell">).*?(?:<h[0-9]>|<strong>)[^\n]*python[^\n]*(?=</h[0-9]>|</strong>)',w.lower(),re.DOTALL))<2and int(R('(?<="vote-count-post ">)[0-9]+',w)[0])>3and w.count('answercell">')>5)
 else:
  P=[];U=[];K=[]
  for i in range(2,t+2):P.append(len(R('(?<=answercell">).*?(?:<h[0-9]>|<strong>)[^\n]*python[^\n]*(?=</h[0-9]>|</strong>)',w.lower(),re.DOTALL)));U.append(int(R('(?<="vote-count-post ">)[0-9]+',w)[0]));K.append(w.count('answercell">'));w=bytes.decode(u.urlopen('http://ppcg.lol/questions/'+o+'/?page='+str(i)).read())
  print(sum(P)<2and U[0]>3and sum(K)>5);print('# Python answers: ',sum(P));print('# Votes: ',U[0]);print('# Answers: ',sum(K))

Dość długo, prawda? Tak naprawdę nie grałem w golfa kodowego, ale jeśli chcesz, mogę trochę pograć w golfa. W przeciwnym razie uwielbiam to i nie mogłabym być szczęśliwsza. Och, prawie zapomniałem, jako dodatkowy bonus, daje to również całkowitą liczbę odpowiedzi Pythona na pytanie, całkowitą liczbę głosów na pytanie i całkowitą liczbę odpowiedzi na pytanie, jeśli pytanieid odpowiada więcej niż jednej stronie odpowiedzi. W przeciwnym razie, jeśli pytanie składa się tylko z jednej strony odpowiedzi, po prostu wyświetla truthy/falsywartość. Naprawdę dałem się ponieść wyzwaniu.

Każdy z nich przyjmuje pytanie idw formie ciągu .

Umieściłbym Try It Online!tutaj linki do każdej funkcji, ale niestety nie pozwala repl.itani Ideonena pobieranie zasobów przez urllibbibliotekę Pythona .

R. Kap
źródło
Możesz użyć, http://codegolf.stackexchange.com/q/aby pobrać pytanie. Czy jest również http://obowiązkowy?
Marv
Ideone i repl.it nie pozwalają na pobieranie zewnętrznych zasobów a la urllib.
Mego
@Mego Dang ... no cóż, myślę, że ludzie będą musieli potwierdzić, że działa przy użyciu własnych interpreterów języka Python.
R. Kap
@Marv Tak, najwyraźniej tak jest. W przeciwnym razie pojawia się unknown url typebłąd.
R. Kap
6
ppcg.lol/q/iddziała również
usunięto
4

Julia, 275 bajtów

using Requests
f(q,p=(s,t)->JSON.parse(readall(get("https://api.stackexchange.com/2.2/questions/$q$s",query=Dict(:site=>"codegolf",:filter=>"$t"))))["items"],x=p("","")[1])=x["answer_count"]>5&&x["score"]>3&&count(i->ismatch(r"python",i["body"]),p("/answers","!9YdnSMKKT"))<2

Jest to funkcja, która przyjmuje liczbę całkowitą i zwraca wartość logiczną. Łączy się z interfejsem API wymiany stosów i każde uruchomienie tej funkcji powoduje wysłanie 2 żądań interfejsu API, więc nie uruchamiaj jej zbyt wiele razy, w przeciwnym razie wyczerpiesz swoje 300 żądań dziennie.

Nie golfowany:

using Requests

function f(q)
    # Define a function that takes two strings and returns a Dict
    # that connects to the SE API
    p = (s,t) -> JSON.parse(readall(get("https://api.stackexchange.com/2.2/questions/$q$s",
        query = Dict(:site => "codegolf", :filter=> "$t"))))["items"]

    # Get the question object
    x = p("", "")[1]

    # Get all answers using the `withbody` API filter
    y = p("/answers", "!9YdnSMKKT")

    x["answer_count"] > 3 && x["score"] > 5 &&
        count(i -> ismatch(r"python", i["body"], y) < 2
end
Alex A.
źródło
Nie wiedziałem o filtrze API „withbody”! +1. Jeśli zapisuje bajty w mojej odpowiedzi Ruby, czy mogę również użyć tej sztuczki?
Wartość tuszu
1
@ KevinLau-notKenny Oczywiście! Rób to, co musisz zrobić w imię golfa. : P
Alex A.
Nie chciałem plagiatować = 3, ale niestety, po zapoznaniu się z ppcg.lolkrótkim linkiem do wszystkich rzeczy codegolf, wersja API po prostu nie wystarczyła
Value Ink
4

Rakieta, 339 bajtów

(λ(q)((λ(h)((λ(g)((λ(j)(and(>(h j'score)3)(>(h j'answer_count)5)(<(for/sum([a(g"~a/answers"q)]#:when(regexp-match #rx"(?i:python)"(h a'body)))1)2)))(car(g"~a"q))))(λ(s d)(define-values(x y b)(http-sendrecv"api.stackexchange.com"(format"/2.2/questions/~a?site=codegolf&filter=withbody"(format s d))))(h(read-json b)'items))))hash-ref))

Wciąż jest wiele do golfa.

Winny
źródło
1
Pokonaj mnie do tego! : P
cat
DO ZROBIENIA: stwórz rakietę podobną do gry w golfa. :)
Winny
1
339 bajtów, z czego 68 to pareny ... więc LISP do gry w golfa potrzebuje krótkich identyfikatorów i żadnych parens. Niezbyt LISPy :(
kot
4

Ruby + HTTParty , 170 146 145 142 139 138 + 11 ( -rhttpartyflaga) = 181 157 156 153 150 150 149 bajtów

Nie sądzę, aby były jakieś przypadki krawędzi, które spowodowałyby zerwanie moich wzorców wyrażeń regularnych, mam nadzieję ...

Zaktualizowano do krótkiego linku dostarczonego przez @WashingtonGuedes i odkrywam, że HTTParty nie narzeka, jeśli zacznę od //zamiast http://.

Zaktualizowano dla nieco bardziej bezpiecznych wyrażeń regularnych. I tak zapisałem bajty, odkrywając, że obiekty odpowiedzi HTTParty dziedziczą po String, co oznacza, że ​​nie muszę ich nawet używać .bodypodczas dopasowywania wyrażenia regularnego!

@manatwork zwrócił uwagę na przypadkowe dodanie postaci, które zostawiłem, i ze względu na golfa inależy teraz zaakceptować jako String.

Zaktualizowano wyrażenia regularne. Ta sama długość. -1 bajt, wycinając paren.

->i{/"up.*?(\d+)/=~s=HTTParty.get("//ppcg.lol/q/"+i)
$1.to_i>3&&(a=s.scan /st.*xt".*\n(.*)/).size>5&&a[1..-1].count{|e|e[0]=~/python/i}<2}

Dodatkowe uwagi:

  • Pierwszy wiersz odpowiedzi (który powinien zawierać język zgodnie ze specyfikacją) to dwa wiersze po znaczniku HTML z klasą "post-text", z którym dopasowaliśmyst.*xt" . Bardziej bezpieczna wersja dodałaby po niej spację, ale poświęcamy to ze względu na golfa.
  • Protokół HTTParty jest używany w net/httpmodułach macierzystych ze względu na odpowiednią obsługę przekierowań dla podanego adresu URL.
  • "up*?\dbyła najkrótszą sekwencją, którą znalazłem, odpowiadającą liczbie głosów. Potrzebujemy tylko pierwszego, więc na szczęście odpowiedzi na to nie wpływają.
Wartość tuszu
źródło
3
ppcg.lol/q/#{i}działa również
usunięto
@WashingtonGuedes ppcg.ga/q#{i}może? (Nie znam Ruby)
Erik the Outgolfer
@ ΈρικΚωνσταντόπουλος ppcg.ga nie jest przekierowaniem wieloznacznym, spróbuj sam - ppcg.ga/q/79273
Timtech
@Timtech Więc jak ppcg.lol/q#{i}to możliwe myślę? ( a/#bjest taki sam jak a#b)
Erik the Outgolfer
1
"Rujnuje /"e-c.*?(\d+)/wyrażenie regularne. Nawiasem mówiąc, wymóg powiedzieć o wejście że „Typy danych (...) nie ma znaczenia.” Więc lepiej zdać í parametr jako ciąg, więc można zastąpić Podstawienie konkatenacji: "//ppcg.lol/q/"+i.
manatwork
3

Groovy, 179 161 157

{i->t=new URL("http://ppcg.lol/q/$i").text;a=0;p=0;(t=~/"(?i)p.{25}>\n.*python/).each{p++};(t=~/(?m)v.{13}t ">(\d+)/).each{if(it[1].toLong()>3)a++};a>5&&p<2}

Dzięki Timtech zapisano 17 znaków.

Słowo kluczowe def również nie jest konieczne.

Krzysztof Atłasik
źródło
Możesz zamienić codegolf.stackexchange.com na ppcg.lol
Timtech