Determinar se vale a pena responder a um desafio

21

Eu sou um jogador de código muito casual e quase não vejo postagens até que elas apareçam na barra lateral "Hot Network Questions" no StackOverflow. Normalmente, estou atrasado para o jogo e, como a única linguagem que conheço é Python, não adianta responder porque já existem várias respostas em Python. Seu desafio é descobrir se vale a pena responder a uma pergunta.

Entrada:

  • Seu código (função ou programa) terá um parâmetro de entrada i

Saída:

  • Valor Truthy ou Falsey para o ID da pergunta i. Saída Verdadeiramente se a pergunta tiver mais de 5 respostas, maior que 3 pontos e uma ou menos resposta no Python (sem distinção entre versões).

Regras / Esclarecimentos:

  • O formato de entrada pode ser qualquer coisa razoável (stdin, arquivo, linha de comando), mas deve ser especificado em sua resposta. Tipos de dados e espaços em branco à esquerda / à direita não importam.
  • Suponha que o ID da pergunta seja válido para codegolf.stackexchange.com.
  • Ignore os requisitos de perguntas específicas do idioma. (ou seja, se uma pergunta encontra votos e respostas e não possui respostas em Python porque é apenas Java, ainda resulta em Truthy).
  • Uma resposta se qualifica como resposta em Python se "python" (sem distinção entre maiúsculas e minúsculas) ocorrer em qualquer lugar antes da primeira nova linha da postagem.
  • Este é o código golf, pelo que o código mais curto em bytes vence.

Casos de amostra *

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)

* Verificado no momento da postagem, pode ter sido alterado

wnnmaw
fonte
Eu também só sei Python ...
R. Kap
Eu também conheço Python, principalmente.
User48538
Eu tenho que começar a aprender algumas outras línguas.
R. Kap
5
@ R.Kap, esse desafio seria um ótimo momento para começar!
Wnnmaw
2
Vale a pena responder a esse desafio, aparentemente.
Rɪᴋᴇʀ

Respostas:

8

05AB1E , 167 160 159 158 156 154 143 bytes

Porra, quase enquanto uma linguagem normal ...

Porcaria ... mais atualmente batendo a resposta do Ruby por 1 byte.

Agora mais do que a resposta do Ruby, argh! .

Eu provavelmente deveria ir para a cama agora.

Obrigado a @wnnmaw por economizar 1 byte e obrigado a @R. Kap por salvar outros 2 bytes!

Código:

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

Ou com mais legibilidade:

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

Explicação:

Primeiro de tudo, muito texto está sendo compactado aqui, o que se traduz no bom e velho Python. A versão não compactada é:

"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

Esta parte:

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

na verdade, exibe um valor de pilha, copia-o no URL e busca todos os dados HTML. Os dados HTML são colocados no topo da pilha usando#.append(f.read()) .

Contamos o número de respostas , contamos o número de ocorrências de class="answer".

Para contar o número de votos, apenas dividimos os dados em "úteis e claros" e mantemos apenas os valores dos dígitos de [0:99] uso ®"useful and clear"¡`99£þ. Este é o número de votos.

Eventualmente, precisamos verificar todas as respostas se o texto "Python"existir antes do texto do cabeçalho de fechamento. Para obter todas as respostas, basta dividir os dados emclass="post-text" e dividir cada uma delas novamente <. Removemos os dois primeiros elementos para obter a parte em que o idioma é exibido e verificamos se a versão em minúscula está nessa sequência.

Então, agora nossa pilha fica assim para id = 79273:

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

Isso também pode ser visto com o -dsinalizador ebug no intérprete.

Portanto, é apenas uma questão de processar os dados:

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

Usa a codificação CP-1252 . Você pode baixar o intérprete aqui .

Adnan
fonte
12
Eu gosto da versão "mais legível"; essas quebras de linha extras realmente fazem a diferença! ;)
Curinga
@Wildcard Eles, de fato, fazer a diferença;)
Erik o Outgolfer
Você pode salvar bytes usando ppcg.lol/q/idcompactação?
Wnnmaw
@wnnmaw Obrigado, agora estou a apenas 1 byte da resposta do Ruby: p.
Adnan
11
Ah não! Eu não acho que posso cortar cantos suficientes para salvar os 7 bytes que preciso para avançar novamente ... Acho que só tenho que me contentar com o segundo lugar
Value Ink
5

Python 3.5, 280 272 260 242 240 bytes:

( Obrigado a Adnan pelo truque sobre o uso do *operador nas comparações que resultam em 2 bytes salvos! )

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)

Simples o suficiente. Usa a urllibbiblioteca interna do Python para acessar o site da pergunta e, em seguida, usa expressões regulares para encontrar a contagem de votos, a contagem de respostas e a contagem de respostas específicas do Python no texto decodificado retornado do site. Por fim, esses valores são comparados com as condições necessárias para retornar um truthyvalor e, se satisfizerem todas as condições,True retornados. Caso contrário, Falseé.

A única coisa que me preocupa aqui é que as expressões regulares dão muita margem de manobra nos termos do número de respostas específicas de python para salvar bytes, portanto pode ser um pouco impreciso às vezes, embora provavelmente seja bom o suficiente para os propósitos deste desafio. No entanto, se você quiser uma mais precisa, adicionei uma abaixo, embora seja mais longa que a acima. O mostrado abaixo tem atualmente 298 bytes, pois usa uma expressão regular muito mais longa - uma que você não sabia quanto tempo levou para descobrir - para contar respostas em Python do que minha função original por uma questão de precisão. Este deve funcionar para pelo menos 80% a 90% de todos os casos de teste lançados nele.

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)

Mas, e essas perguntas com várias páginas de respostas? Nenhuma das opções acima funcionará muito bem nessa situação, se, por exemplo, 1 resposta python estiver na primeira página e outra na segunda. Bem, tomei a liberdade de corrigir esse problema criando outra versão da minha função (mostrada abaixo) que verifica todas as páginas de respostas, se existirem múltiplas, para respostas do Python, e tem se saído muito bem em muitos dos casos de teste que eu jogou nele. Bem, sem mais delongas, aqui está a função nova e atualizada:

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

Muito tempo, não é? Eu realmente não estava gostando muito de código de golfe com isso, embora, se você quiser, eu possa jogar um pouco mais. Caso contrário, eu amo isso e não poderia ser mais feliz. Ah, eu quase esqueci, como um bônus adicional, isso também gera o número total de respostas Python na pergunta, total de votos na pergunta e número total de respostas na pergunta, se a perguntaid corresponder a uma pergunta com mais de uma página de respostas. Caso contrário, se a pergunta consistir apenas em uma única página de respostas, ela emitirá apenas otruthy/falsy valor. Eu realmente me empolguei um pouco com esse desafio.

Cada um deles leva a pergunta idna forma de um string .

Eu colocaria Try It Online!links aqui para cada função, mas infelizmente, repl.itnem Ideonepermitimos a busca de recursos através da urllibbiblioteca do Python .

R. Kap
fonte
Você pode usar http://codegolf.stackexchange.com/q/para buscar a pergunta. Além disso, é http://obrigatório?
Marv
Ideone e repl.it não permitem buscar recursos externos à la urllib.
Mego
@Mego Dang ... bem, acho que as pessoas terão que confirmar que funciona usando seus próprios intérpretes Python.
R. Kap
@ Marv Sim, aparentemente é. Caso contrário, eu recebo umunknown url type erro.
R. Kap
6
ppcg.lol/q/idtambém funciona
removido
4

Julia, 275 bytes

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

Esta é uma função que aceita um número inteiro e retorna um booleano. Ele se conecta à API do Stack Exchange e cada execução da função faz 2 solicitações de API. Portanto, não execute-a muitas vezes ou você esgotará sua cota de 300 solicitações / dia.

Ungolfed:

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.
fonte
Eu não conhecia o filtro de API "withbody"! +1. Se ele salvar bytes na minha resposta Ruby, também posso usar esse truque?
Value Ink
11
@ KevinLau-notKenny Claro! Faça o que você precisa fazer em nome do golfe. : P
Alex A.
Eu não queria plagiar = 3 mas, infelizmente, depois de saber ppcg.lolcomo um link curto para todas as coisas codegolf, a versão da API só não foi suficiente
Valor Ink
4

Raquete, 339 bytes

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

Ainda há muito para jogar golfe.

Winny
fonte
11
Bata em mim! : P
cat
TODO: faça uma raquete que seja capaz de jogar golfe. :)
Winny
11
339 bytes, dos quais 68 são parênteses ... portanto, um LISP para golfe precisaria de identificadores curtos e sem parênteses. Não é muito LISPy :(
cat
4

Ruby + HTTParty , 170 146 145 142 139 138 + 11 ( -rhttpartysinalizador) = 181 157 156 153 153 150 149 bytes

Eu acho que não há casos extremos que causem a quebra dos meus padrões regex, espero ...

Atualizado para o atalho fornecido por @WashingtonGuedes e descobrindo que HTTParty não reclama se eu começar com em //vez dehttp:// .

Atualizado para regexes um pouco mais seguras. De qualquer maneira, salvei bytes ao descobrir que os objetos de resposta HTTParty herdam da String, o que significa que eu nem preciso usar .bodyao corresponder ao regex!

O @manatwork apontou que um acréscimo acidental de caracteres que eu havia deixado, e pelo bem do golfe, ideve ser aceito como uma String agora.

Regexes atualizadas. Mesmo comprimento. -1 byte cortando um 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}

Notas extras:

  • A primeira linha de uma resposta (que deve conter o idioma de acordo com as especificações) é de duas linhas após a tag HTML com a classe "post-text", com a qual combinamosst.*xt" . Uma versão mais segura teria acrescentado um espaço a seguir, mas estamos sacrificando isso por causa do golfe.
  • HTTParty é usado nos net/httpmódulos nativos devido ao tratamento adequado do redirecionamento para a URL especificada.
  • "up*?\dfoi a sequência mais curta que achei que correspondia ao número de votos. Precisamos apenas do primeiro, então, felizmente, as respostas não afetam isso.
Value Ink
fonte
3
ppcg.lol/q/#{i}também funciona
removido
@WashingtonGuedes ppcg.ga/q#{i}talvez? (Não conheço Ruby)
Erik the Outgolfer
@ ΈρικΚωνσταντόπουλος ppcg.ga não é um redirecionamento curinga, experimentar por si mesmo - ppcg.ga/q/79273
Timtech
@ Timtech Então ppcg.lol/q#{i}é aplicável, eu acho? ( a/#bé o mesmo que a#b)
Erik the Outgolfer
11
O "está a arruinar a /"e-c.*?(\d+)/expressão regular. By the way, a exigência dizer sobre a entrada que “tipos de dados (...) não importa.” Então é melhor passar o parâmetro i como corda, para que você possa substituir substituição com concatenação: "//ppcg.lol/q/"+i.
manatwork 5/05
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}

Graças ao Timtech 17 caracteres salvos.

A definição de palavra- chave também não é necessária.

Krzysztof Atłasik
fonte
Você pode substituir codegolf.stackexchange.com com ppcg.lol
Timtech
veja também: Dicas para golfe em Groovy
gato