Déterminer si un défi mérite d'être répondu

21

Je suis un golfeur de code très occasionnel, et je ne vois pas souvent de messages jusqu'à ce qu'ils apparaissent dans la barre latérale "Hot Network Questions" sur StackOverflow. Habituellement, je suis en retard dans le jeu, et puisque le seul langage que je connais est le Python, il est inutile de répondre car il existe déjà plusieurs réponses Python. Votre défi consiste à déterminer si une question mérite que je réponde.

Contribution:

  • Votre code (fonction ou programme) prendra un paramètre d'entrée i

Sortie:

  • Valeur Truthy ou Falsey pour l'identifiant de la question i. Sortez Truthy si la question a plus de 5 réponses, un score supérieur à 3 et une ou moins de réponses en Python (aucune distinction entre les versions).

Règles / clarifications:

  • Le format d'entrée peut être quelque chose de raisonnable (stdin, fichier, ligne de commande), mais doit être spécifié dans votre réponse. Les types de données et les espaces de début / fin n'ont pas d'importance.
  • Supposons que l'ID de la question est valide pour codegolf.stackexchange.com.
  • Ignorez les exigences de questions spécifiques à la langue. (c.-à-d. si une question rencontre des votes et des réponses, et n'a pas de réponses Python parce qu'elle n'est que Java, cela donne toujours Truthy).
  • Une réponse est considérée comme une réponse Python si "python" (insensible à la casse) se produit n'importe où avant la première nouvelle ligne du message.
  • C'est le golf de code, donc le code le plus court en octets gagne.

Exemples de cas *

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)

* Vérifié au moment de la publication, peut avoir changé

wnnmaw
la source
Je ne connais aussi que Python ...
R. Kap
Je connais également Python principalement.
user48538
Je dois commencer à apprendre d'autres langues.
R. Kap
5
@ R.Kap, ce défi serait le moment idéal pour commencer!
wnnmaw
2
Ce défi mérite apparemment d'être relevé.
Rɪᴋᴇʀ

Réponses:

8

05AB1E , 167 160 159 158 156 156 154 143 octets

Merde, presque aussi longtemps qu'une langue normale ...

Merde ... plus bat actuellement la réponse Ruby de 1 octet.

Maintenant plus long que la réponse Ruby, argh! .

Je devrais probablement aller me coucher maintenant.

Merci à @wnnmaw d'avoir sauvé 1 octet et merci à @R. Kap pour économiser encore 2 octets!

Code:

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

Ou avec plus de lisibilité:

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

Explication:

Tout d'abord, beaucoup de texte est compressé ici, ce qui se traduit par un bon vieux Python. La version non compressée est:

"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

Cette partie:

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

fait apparaître une valeur de pile, la copie dans l'url et récupère toutes les données HTML. Les données HTML sont poussées en haut de la pile à l'aide de #.append(f.read()).

Nous comptons le nombre de réponses , en comptant le nombre d'occurrences de class="answer".

Pour compter le nombre de votes, nous venons de diviser les données à "utiles et claires" et de ne garder que les valeurs numériques de l' [0:99]utilisation ®"useful and clear"¡`99£þ. Ceci est le nombre de votes positifs.

Finalement, nous devons vérifier chaque réponse si le texte "Python"existe avant le texte de l'en-tête de fermeture. Pour obtenir toutes les réponses, nous divisons simplement les données class="post-text"et nous les divisons à nouveau <. Nous supprimons les deux premiers éléments pour obtenir la partie dans laquelle la langue est affichée et vérifions si la version minuscule est dans cette chaîne.

Donc, maintenant notre pile ressemble à ceci pour id = 79273:

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

Cela peut également être vu avec le -ddrapeau ebug dans l'interpréteur.

Il s'agit donc simplement de traiter les données:

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

Utilise l' encodage CP-1252 . Vous pouvez télécharger l'interprète ici .

Adnan
la source
12
J'aime la version "plus lisible"; ces sauts de ligne supplémentaires font vraiment une différence! ;)
Wildcard
@Wildcard Ils font vraiment la différence;)
Erik the Outgolfer
Pourriez-vous économiser des octets en utilisant la ppcg.lol/q/idcompression?
wnnmaw
@wnnmaw Merci, maintenant je ne suis qu'à 1 octet de la réponse Ruby: p.
Adnan
1
Oh non! Je ne pense pas que je puisse couper assez de coins pour économiser les 7 octets dont j'ai besoin pour avancer à nouveau ... Je suppose que je dois juste me contenter de la deuxième place
Value Ink
5

Python 3.5, 280 272 260 242 240 octets:

( Merci à Adnan pour l'astuce sur l'utilisation de l' *opérateur dans les comparaisons résultant en 2 octets enregistrés! )

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)

Assez simple. Utilise la urllibbibliothèque intégrée de Python pour accéder au site de la question, puis utilise des expressions régulières pour trouver le nombre de votes, le nombre de réponses et le nombre de réponses spécifiques à Python dans le texte décodé renvoyé par le site Web. Enfin, ces valeurs sont comparées aux conditions requises pour renvoyer une truthyvaleur, et si elles remplissent toutes les conditions, elles Truesont renvoyées. Sinon, Falsec'est.

La seule chose qui peut m'inquiéter ici, c'est que les expressions régulières donnent beaucoup de latitude en termes de nombre de réponses spécifiques à python pour économiser des octets, donc cela peut être un peu inexact parfois, bien que ce soit probablement assez bon pour les objectifs de ce défi. Cependant, si vous en voulez un beaucoup plus précis, j'en ai ajouté un ci-dessous, bien que son plus long que celui ci-dessus. Celui montré ci-dessous est actuellement de 298 octets car il utilise une expression régulière beaucoup plus longue - celle que vous ne pouviez pas savoir combien de temps il m'a fallu pour découvrir - pour compter les réponses Python que ma fonction d'origine pour des raisons de précision. Celui-ci devrait fonctionner pour au moins 80% à 90% de tous les cas de test qui y sont lancés.

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)

Mais qu'en est-il de ces questions avec plusieurs pages de réponses? Aucune des réponses ci-dessus ne fonctionnera très bien dans cette situation, si, disons, 1 réponse python se trouve sur la première page et une autre sur la seconde. Eh bien, j'ai pris la liberté de résoudre ce problème en créant une autre version de ma fonction (illustrée ci-dessous) qui vérifie chaque page de réponses, s'il en existe plusieurs, pour les réponses Python, et cela a très bien fonctionné sur de nombreux cas de test que je l'ont jeté. Eh bien, sans plus tarder, voici la nouvelle fonction mise à jour:

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

Assez longtemps, non? Je n'allais pas vraiment beaucoup pour le golf de code avec cela, bien que, si vous voulez, je puisse le jouer un peu plus. Sinon, je l'adore et je ne pourrais pas être plus heureux. Oh, j'ai presque oublié, en bonus supplémentaire, cela génère également le nombre total de réponses Python sur la question, le nombre total de votes sur la question et le nombre total de réponses sur la question si la question idcorrespond à une question de plus de 1 page des réponses. Sinon, si la question ne se compose que d'une seule page de réponses, elle renvoie simplement la truthy/falsyvaleur. J'ai vraiment été un peu emporté par ce défi.

Ceux-ci prennent chacun la question idsous la forme d'une chaîne .

Je mettrais des Try It Online!liens ici pour chaque fonction, mais malheureusement, repl.itni Ideoneautoriser la récupération de ressources via la urllibbibliothèque de Python .

R. Kap
la source
Vous pouvez utiliser http://codegolf.stackexchange.com/q/pour récupérer la question. Aussi, est-ce http://obligatoire?
Marv
Ideone et repl.it ne permettent pas de récupérer des ressources externes à la urllib.
Mego
@Mego Dang ... eh bien, je suppose que les gens vont devoir confirmer que cela fonctionne en utilisant leurs propres interprètes Python.
R. Kap
@Marv Oui, apparemment c'est le cas. Sinon, j'obtiens une unknown url typeerreur.
R. Kap
6
ppcg.lol/q/idfonctionne également
supprimé
4

Julia, 275 octets

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

Il s'agit d'une fonction qui accepte un entier et renvoie un booléen. Il se connecte à l'API Stack Exchange et chaque exécution de la fonction fait 2 demandes d'API, alors ne l'exécutez pas trop de fois ou vous épuiserez votre quota de 300 demandes / jour.

Non golfé:

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.
la source
Je n'étais pas au courant du filtre d'API "withbody"! +1. S'il enregistre des octets sur ma réponse Ruby, puis-je également utiliser cette astuce?
Value Ink
1
@ KevinLau-notKenny Bien sûr! Faites ce que vous devez faire au nom du golf. : P
Alex A.
Je ne voulais pas plagier = 3 mais hélas, après avoir appris ppcg.lolcomme un lien court vers tout le codegolf, la version de l'API n'était tout simplement pas suffisante
Value Ink
4

Raquette, 339 octets

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

Il y a encore beaucoup à jouer au golf.

Winny
la source
1
Battez-moi! : P
chat
TODO: fabriquez une raquette semblable au golf. :)
Winny
1
339 octets dont 68 sont des parens ... donc un LISP pour le golf aurait besoin d'identifiants courts et pas de parens. Pas très LISPy :(
cat
4

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

Je ne pense pas qu'il y ait des cas marginaux qui pourraient casser mes schémas d'expression rationnelle, j'espère ...

Mise à jour du lien court fourni par @WashingtonGuedes et découverte que HTTParty ne se plaint pas si je commence par //au lieu de http://.

Mis à jour pour des expressions rationnelles légèrement plus sécurisées. J'ai quand même économisé des octets en découvrant que les objets de réponse HTTParty héritent de String, ce qui signifie que je n'ai même pas besoin d'utiliser pour faire .bodycorrespondre l'expression régulière!

@manatwork a souligné un ajout de personnage accidentel que j'avais laissé et, pour le golf, idoit maintenant être accepté comme une chaîne.

Regex mis à jour. Même longueur. -1 octet en supprimant une 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}

Notes supplémentaires:

  • La première ligne d'une réponse (qui devrait contenir la langue selon la spécification) est deux lignes après la balise HTML avec classe "post-text", avec laquelle nous avons fait correspondrest.*xt" . Une version plus sécurisée aurait ajouté un espace après, mais nous sacrifions cela pour le golf.
  • HTTParty est utilisé sur les net/httpmodules natifs en raison de la bonne gestion de la redirection pour l'URL donnée.
  • "up*?\détait la séquence la plus courte que j'ai trouvée qui correspondait au nombre de votes. Nous n'avons besoin que du premier, donc heureusement les réponses n'affectent pas cela.
Encre de valeur
la source
3
ppcg.lol/q/#{i}fonctionne également
supprimé
@WashingtonGuedes ppcg.ga/q#{i}peut-être? (Je ne connais pas Ruby)
Erik the Outgolfer
@ ΈρικΚωνσταντόπουλος ppcg.ga n'est pas une redirection générique, essayez-le vous-même - ppcg.ga/q/79273
Timtech
@Timtech Est-ce donc ppcg.lol/q#{i}applicable je pense? ( a/#best le même que a#b)
Erik the Outgolfer
1
Le "ruine l' /"e-c.*?(\d+)/expression régulière. Soit dit en passant, par exemple l'exigence de l'entrée que « types de données (...) n'a pas d' importance. » Il vaudrait donc mieux passer le paramètre i sous forme de chaîne, de sorte que vous pouvez remplacer la substitution par concaténation: "//ppcg.lol/q/"+i.
manatwork
3

Groovy, 179 161 157 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}

Merci à Timtech 17 caractères sauvés.

Mot - clé def est pas nécessaire.

Krzysztof Atłasik
la source
Vous pouvez remplacer codegolf.stackexchange.com par ppcg.lol
Timtech