¿Cuánta recompensa hay en Stackoverflow?

33

Tarea:

Eres un programador increíble y un respondedor de Stackoverflow, y decides responder cada pregunta con una recompensa en Stackoverflow. Eres tan bueno que logras obtener todas las recompensas en todas las preguntas. Mientras espera que llegue el representante, se escribe un programa que va y descubre cuál es la cantidad total de representante en todas esas recompensas.

Reglas:

  • Cuando se ejecuta,
    • Su programa navegará por la pestaña destacada en Desbordamiento de pila.
    • Raspará el valor de cada recompensa,
    • Luego lo sumará y mostrará el total
  • Tiene que descargar datos desde cualquier lugar en SO (y solo SO), pero recomendaría usar https://stackoverflow.com/questions?pagesize=50&sort=featured , ya que solo tiene aproximadamente 10 páginas.
  • Este es el , por lo que gana el código más corto
TheDoctor
fuente
2
stackoverflow.com/?tab=featured . Todas las preguntas destacadas en 1 página.
Nzall 01 de
77
@NateKerkhofs no son todos ellos. Desplácese hasta la parte inferior. por ejemplo, cuando lo cargué, mostraba 96 de 472 preguntas.
bazzargh 01 de
Bounty API
solo el
@justhalf ya ha sido discutido ...
TheDoctor

Respuestas:

23

JavaScript - 176 133 130 108 106

function f()(t+=$("[title~=an]").text(),u=$("[rel*=x]")[0])?$("html").load(u.href,f):alert(eval(t));f(t=0)

Edición 1: recorté algunos selectores y utilicé la ?:sugerencia del Compilador de cierre de Google (a través de @Sirko, gracias)

Edición 2: inicializar sdentro de inicializar tcomo en 0lugar de""

Edición 3: me di cuenta de que en realidad no necesito apuntar a un contenedor específico y puedo barrer todo el documento, lo que elimina un montón de .findllamadas y un selector innecesario (más la variable que lo contiene)

Edición 4: inserte el tinicializador en la llamada a la función para evitar a ;(de todos modos se izará al principio) y reduzca la función a una declaración (combine dos declaraciones en una dentro de la condición de declaración ternaria) para soltar el{}

Nota : No estoy seguro de si es trampa, pero esto debe ejecutarse desde una ventana de consola de un navegador que ya apunta http://stackoverflow.com/questions?page=1&sort=featured. Se basa en el hecho de que jQuery y los enlaces de paginación apropiados están disponibles en la página misma. Además, solo parece funcionar en Firefox y no en IE o Chrome.

Salida (en el momento de la publicación):

38150 (in an alert dialog)

Explotado / comentado :

function f()
    //concat all the bounty labels to t (they take the format "+50")
    //happens to be elements with title attribute containing word 'an'
    (t+=$("[title~=an]").text(),
    //find the "next" (has rel=next attribute) button
    u = $("[rel*=x]")[0])       
        ?
        //if there is a next button, load it, and then recurse f again
        $("html").load(u.href,f)
        :
        //else eval the 0+a+b+...+z tally and alert the result
        alert(eval(t))
//kick off the initial scrape (and simultaneously init the total tally)
f(t=0)
Alconja
fuente
s=" #mainbar";d=$(s);t="";function a(){d.find(".bounty-indicator").each(function(){t+=this.innerHTML});(u=d.find("[rel=next]")[0])?d.load(u.href+s,a):alert(eval(t))}a();169 - compilador de cierre de Google usado.
Sirko
8
¡Elección astuta de lenguaje y contexto para evitar muchos de los caracteres requeridos! (Como " stackoverflow.com/" ) ¡Me gusta!
AlexC
Creo que deberías mencionar que se hace usando el complemento jQuery. que creo que debería ser .. :)
Mr_Green
Chrome arroja un error de sintaxis. Abrir un cuerpo de función con un (par, ¿realmente funciona?
thejh
@ Mr_Green - Ya lo noté, pero lo he marcado para llamar más la atención ...
Alconja
21

Python - 232, 231, 195, 183, 176174

Analiza el HTML de https://stackoverflow.com/questions?sort=featured usando expresiones regulares.

El límite superior de rangeen el forbucle debe ser number of pages + 1o el código aumentará HTTPErrordebido a los 404. El número predeterminado de resultados por página es 15, que es lo que usa el código (omitir ?pagesize=50guardar en caracteres y es igual de efectivo).

Gracias a @Gabe por el consejo de reducir aún más el recuento de char.

Golfizado :

import requests,re;print sum(sum(map(int,re.findall(r"<.*>\+(\d+)<.*>",requests.get("https://stackoverflow.com/questions?sort=featured&page=%u"%i).text)))for i in range(1,33))

Salida (en el momento de la publicación):

37700

Sin golf :

Aquí hay una versión un tanto inexperta que debería ser un poco más fácil de leer y comprender.

import requests, re

print sum(
          sum(
              map( int,
                   re.findall( r"<.*>\+(\d+)<.*>",
                               requests.get( "https://stackoverflow.com/questions?sort=featured&page=%u" % i).text
                   )
              )
          ) for i in range( 1, 33 )
      )
Tony Ellis
fuente
1
Puede deshacerse del forbucle explícito y bajarlo a 176:import urllib,re;print sum(sum(map(int,re.findall(r"<.*>\+(\d+)<.*>",urllib.urlopen("http://stackoverflow.com/questions?sort=featured&page=%u"%i).read())))for i in range(1,33))
Gabe
tener un límite superior codificado hace que sea un poco difícil de probar
Einacio
2
oh dios
wchargin 02 de
66
@ Richard Sí, pero este es el código de golf , por lo que la brevedad triunfa si es una "buena idea". Quiero decir, en la vida real tampoco es una buena idea escribir frases horribles sin espacios en blanco ...
Tim Goodman
3
@ Richard Analizar html y extraer de html son tareas bastante diferentes. Dado que un sitio web no es una API estable, no se garantiza que nada funcione para este tipo de extracción. Aunque el código de Tony está un poco sobrevalorado, fallaría si hay alguna etiqueta que contenga un +seguido de un número. Por ejemplo, el título de una pregunta podría ajustarse a ese formato.
CodesInChaos
18

Rebol - 164 133 130 (139 404 con verificación)

Analiza el html usando el parsesub-idioma de Rebol. Comprueba las primeras 98 páginas. Me di cuenta de que tengo la misma restricción que la solución de Python: demasiadas repeticiones golpean errores 404 y detienen la ejecución. ¡Gracias a @rgchris por muchas mejoras! Actualizado para consultar hasta 98 ​​páginas.

s: 0 repeat n 99[parse read join http://stackoverflow.com/questions?sort=featured&page= n[15[thru{>+}copy x to{<}(s: s + do x)]]]s

Con comprobación de errores para 404s (139):

s: 0 repeat n 99[attempt[parse read join http://stackoverflow.com/questions?sort=featured&page= n[15[thru{>+}copy x to{<}(s: s + do x)]]]]s

Prueba

>> s: 0 repeat n 20[parse read join http://stackoverflow.com/questions?sort=featured&page= n[15[thru{>+}copy x to{<}(s: s + do x)]]]s
== 23600

>> s: 0 repeat n 99[attempt[parse read join http://stackoverflow.com/questions?sort=featured&page= n[15[thru{>+}copy x to{<}(s: s + do x)]]]]s
Script: none Version: none Date: none
== 36050

Explicación

Rebol ignora los espacios en blanco, por lo tanto, si lo desea, puede poner todo en una línea como esa. PARSE toma dos entradas, y el primer argumento ( read join ...) se explica por sí mismo. Pero aquí hay algunos comentarios sobre las instrucciones del dialecto de análisis, en una sangría más tradicional:

s: 0
repeat n 99 [
    parse read join http://stackoverflow.com/questions?sort=featured&page= n [
        ;-- match the enclosed pattern 15 times (the rule will fail politely when there are less entries)
        15 [
            ;-- seek the match position up THRU (and including) the string >+
            thru {>+}
            ;-- copy contents at the current position up TO (but not including) <
            copy x to {<}
            ;-- (Basically, run some non-dialected Rebol if this match point is reached) the do is a bit dangerous as it runs the string as code
            (s: s + do x)
        ]
    ]
]
;-- evaluator returns last value, we want the value in S
;-- (not the result of PARSE, that's a boolean on whether the end of input was reached)
s
johnk
fuente
Agradable ... agregué una versión con formato ordinario con algunos comentarios, ¡espero que no te importe! Siempre es bueno ver qué tan bien Rebol soluciona tantos problemas con tal alfabetización (todo en un ejecutable con licencia de Apache multiplataforma de media meg, pero eso hace que cosas como REFORM se destaquen como un pulgar dolorido) Todo lo demás tiene sentido, pero sigo mirando con esa palabra e ir "REducir y FORMAR convertida en REFORMA" es simplemente feo . Obsesionarse es muy Hawthorne . ¡Oh, y podrías cambiar ALGUNOS a CUALQUIERA y afeitarte un char! :-)
Dr. Rebmu
Vaya, debería ser 133.
rgchris
Nota: necesita pasar a un nvalor más alto ... actualmente hay 28 páginas de recompensas (para el tamaño de página 15). Sin embargo, no afectará tu recuento de char.
Alconja
Gracias Alconja Fácil de subir a 98 páginas antes de agregar más caracteres a la solución. Tendré que volver a ejecutar la prueba desde casa esta noche
johnk
11

Rubí, 260

require'open-uri'
require'zlib'
i=b=0
d=''
until /"has_more":f/=~d
i+=1
d=Zlib::GzipReader.new(open("http://api.stackexchange.com/2.2/questions/featured?site=stackoverflow&page=#{i}&pagesize=100")).read
b+=d.scan(/"bounty_amount":(\d+)/).map{|x|x[0].to_i}.reduce :+
end
p b

Utiliza la API de Stack Exchange.

Salida (al momento de la publicación original):

37200

No estoy contando el recuento &pagesize=100de caracteres, porque funciona sin él, pero acabo de agregarlo por conveniencia durante las pruebas. Si elimina eso, hace lo mismo (excepto que consume más cuota y tarda un poco más).

Pomo de la puerta
fuente
Bien, solo llegué a 275 en Python
Claudiu
¿Come más cuota? Se suponía que debías usar SO y SO solamente.
John Dvorak
@JanDvorak ??? Me refería a la cuota de API.
Pomo de la puerta
1
El requires se puede reemplazar con el -rindicador de línea de comando.
Justin
8

Rebmu - 108 107

rtN99[parseRDrj[http://stackoverflow.com/questions?sort=featured&page=N][15[thru{>+}copyXto{<}(a+JdoX)]]]j

Prueba (a las 19:05 AEST)

>> rebmu [rtN99[parseRDrj[http://stackoverflow.com/questions?sort=featured&page=N][15[thru{>+}copyXto{<}(a+JdoX)]]]j]
Script: none Version: none Date: none
== 79200

Rebmu parece bastante críptico, pero es bastante legible una vez que te . Comencemos por desmoldarlo y colocarlo correctamente.

rt n 99 [
    parse rd rj [
        http://stackoverflow.com/questions?sort=featured&page= n
    ][
        15 [
            thru {>+}
            copy x to {<}
            (a+ j do x)
        ]
    ]
]
j

Rebmu es un dialecto de Rebol para que pueda ver las similitudes en la solución. Rebmu aún no puede reducir el tamaño de cada declaración, pero es un lenguaje en evolución. Gracias de nuevo a @rgchris por las mejoras en mi primer intento.

johnk
fuente
ti(¡a entero!) sería más seguro que doen Rebmu sin cambios en la longitud del código.
rgchris 03 de
6

Rubí - 197

Version corta:

require 'nokogiri'
require 'open-uri'
s=0
(1..33).each{|p|Nokogiri::HTML(open("http://stackoverflow.com/questions?page=#{p}&sort=featured")).css('.bounty-indicator').each{|b|s+=b.content.to_i}}
p s

Versión amigable para los humanos:

require 'nokogiri'
require 'open-uri'
s=0
(1..33).each do |p|
    Nokogiri::HTML(open("http://stackoverflow.com/questions?page=#{p}&sort=featured")).css('.bounty-indicator').each do |b|
        s += b.content.to_i
    end
end
puts s

Y la respuesta - 39700

Ruby con parámetros de script - 139

require 'nokogiri'
require 'open-uri'
s=0
(1..33).each{|p|Nokogiri::HTML(open(ARGV[0]+p.to_s)).css(ARGV[1]).each{|b|s+=b.content.to_i}}
p s

Para ejecutar esto desde bash solo escribe

ruby code_golf_stack_overflow2.rb http://stackoverflow.com/questions?sort=featured\&page= .bounty-indicator
cyriel
fuente
El requires se puede reemplazar con el -rindicador de línea de comando.
Justin
6

PHP - 121 bytes

<?for(;preg_filter('/>\+(\d+)/e','$t+=\1',@file('http://stackoverflow.com/questions?sort=featured&page='.++$n)););echo$t;

Usando un modificador regex 'eval', para evitar usar array_sumo similar. Parece ser la solución más corta entre las entradas válidas.

primo
fuente
44
el emodificador ha quedado en desuso a partir de PHP 5.5, pero aún así es útil para jugar al golf.
Fabrício Matté
6

PHP, 134 , 131 , 127

while($q=array_sum(preg_filter('#.*>\+#',0,file("http://stackoverflow.com/questions?sort=featured&page=".++$n))))$s+=$q;echo$s;

Recorrerá todas las páginas, pagesizeno está configurado para guardar bytes, así que másGET s.

Muy, muy sucio, pero ... ¡aprovechando PHPlos "defectos"!

  • sin espacio después echo
  • while se detiene en la tarea
  • salida después de RegExreemplazar es una cadena que comienza con la cantidad de recompensa
  • array_sum() suma cadenas
  • $n y $s se inicializan, pero a partir de nada es equiv. como a partir de cero
  • etc ...
CSᵠ
fuente
5

Bash 206

optimizaciones posibles, demasiado vago

s=0;for i in `seq 1 11`;do for j in `wget -q -O - "http://stackoverflow.com/questions?pagesize=50&sort=featured&page=$i" | grep -o -E "bounty worth [0-9]*" | grep -o -E "[0-9]*"`;do s=$(($s+$j));done;done;echo $s

resultado:

39450
usuario19998
fuente
44
Podría estar equivocado, pero parece que podría ser muy corto con algunas optimizaciones de calidad.
rickcnagy
seq 1 11se puede reducir a seq 11.
fedorqui
Debería poder deshacerse de los espacios alrededor de las tuberías para guardar cuatro caracteres, y seguramente esos dos greps pueden fusionarse en uno (¿quiso decir "[0-9] +"?).
Desty
También "grep -o -E" => "egrep -o".
Desty
Y puede cambiar: "egrep -o '[0-9] +'" => "cut -d '' -f3" :)
Desty
5

Javascript - 129 129 119 110 107 caracteres

EDITAR: ¡RESPUESTA NO VÁLIDA! Esto solo maneja las "Preguntas destacadas", que solo tiene una fracción de ellas. La respuesta de Alconja es más válida.

s="#mainbar";t="";eval("$(s).find('.bounty-indicator').each(function(){t+=this.innerHTML});alert(eval(t))")

Ejecute en https://stackoverflow.com/?tab=featured en una ventana de consola. Basado en la solución de Alconja.

Lo jugué un poco más al eliminar espacios en blanco innecesarios.

Se utilizó eval para eliminar la llamada a la función, borrando otros 9 caracteres.

despejó algunos espacios en blanco más innecesarios.

Nzall
fuente
3

Java, 540 caracteres

Advertencia: el número de recompensas activas es ~ 470. Este código accederá a una página en stackoverflow que muchas veces. Puede meterte en problemas con ellos por hacer tantas solicitudes de datos.

import java.io.*;import java.net.*;public class B{public static void main(String[]A){String u="http://stackoverflow.com/questions",d;Long i,s=i=0L,n=i.parseLong(o(u).replaceAll("^.*b.>(\\d+).*$","$1"));while(i++<n){d=o(u+"?pagesize=1&sort=featured&page="+n).replaceAll("^.*ion.>.(\\d+).*$","$1");s+=d.matches(".*\\D.*")?0:n.parseLong(d);}System.out.print(s);}static String o(String s){String d="";try{BufferedReader r=new BufferedReader(new InputStreamReader(new URL(s).openStream()));while((s=r.readLine())!=null)d+=s;}finally{return d;}}}

Mi salida fue 23400 , pero cuando ejecuté el código de @ TonyH, obtuve 37550. Malas noticias.

Código bonito:

import java.io.*;
import java.net.*;

public class StackOverflowBounty {

    public static void main(String[] args) {
        String u = "http://stackoverflow.com/questions", d;
        Long i, s = i = 0L, n = i.parseLong(o(u).replaceAll("^.*b.>(\\d+).*$", "$1"));
        while (i++ < n) {
            d = o(u + "?pagesize=1&sort=featured&page=" + n).replaceAll("^.*ion.>.(\\d+).*$", "$1");
            s += d.matches(".*\\D.*") ? 0 : n.parseLong(d);
        }
        System.out.print(s);
    }

    static String o(String s) {
        String d = "";
        try {
            BufferedReader r = new BufferedReader(new InputStreamReader(new URL(s).openStream()));
            while ((s = r.readLine()) != null) {
                d += s;
            }
        } finally {
            return d;
        }
    }
}

La forma en que esto funciona es simple. Se lee de la urlhttp://stackoverflow.com/questions" para determinar el número de preguntas que tienen recompensas (nota: si el número aumenta, el programa falla, pero si cae, funciona bien). Se busca de este número mediante la expresión regular: b.>(\\d+). Esto ha funcionado en todas las pruebas hasta la fecha, pero si alguien hizo una pregunta que coincida con esa expresión regular, esto podría no funcionar.

Luego, abrimos la url http://stackoverflow.com/questions?pagesize=1&sort=featured&page=+ current question #. En otras palabras, abrimos una nueva página para cada pregunta destacada, y forzamos que el número de preguntas sea solo1 , de modo que las obtengamos todas. La parte de reputación siempre coincidirá ion.>.(\\d+), así que la uso para encontrarla. Dividí la operación en dos partes para poder comprobar de forma económica si se redujo el número de preguntas (es decir, la cadena devuelta no es un número entero).

Luego, resumimos toda la reputación e imprimimos.

Me llevó unos 3 minutos y 20 segundos ejecutar mi máquina.


¿Alguien sabe por qué no está imprimiendo el número correcto?

Justin
fuente
pagesize = 100 da el gran número. Creo que algo extraño está sucediendo porque estás pasando el tamaño de página = 1. En mi respuesta, si no especifiqué 'tamaño de página', el resultado estaba cerca de su número.
jzm 01 de
@malik Sí, me di cuenta de que había "leído mal" tu comentario, así que borré el mío :-). tamaño de página = 100 actúa como si el tamaño de página = 50. ¿Quiso decir que ejecutó mi código con pagesize = 100?
Justin
2

C # - 407

class B{void Main(string[] a){var o=0;for(int i=1;i<11;i++){var r=((System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(new Uri(string.Format(a[0]+"&page={0}",i)))).GetResponse();if(r.ContentLength>0){using(var s=new StreamReader(r.GetResponseStream()))foreach(Match m in Regex.Matches(s.ReadToEnd(),"bounty worth (.+?) "))o+=int.Parse(m.Value.Substring(m.Value.IndexOf('h')+2));}}Console.Write(o);}}

Usando Stackoverflow.com. Igual que a continuación, excepto que no hay descompresión Gzip y diferentes expresiones regulares.

Prueba

> prog.exe http://stackoverflow.com/questions?pagesize=50&sort=featured
38150

Extrañamente, obteniendo un valor diferente al siguiente.


C # - 496

Esto usa api.stackexchange que es gzipped y json.

using System.IO.Compression;class B{void Main(string[] a){var o=0;for(int i=1;i<11;i++){var r=((System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(new Uri(string.Format(a[0]+"&page={0}",i)))).GetResponse();if(r.ContentLength>0)using(var s=new StreamReader(new GZipStream(r.GetResponseStream(),CompressionMode.Decompress)))foreach(Match m in Regex.Matches(s.ReadToEnd(),@"bounty_amount"":(.+?),"))o+=int.Parse(m.Value.Substring(m.Value.IndexOf(':')+1).Replace(",",""));}Console.Write(o);}}

No minificado:

using System.IO.Compression;

class B
{
    void Main(string[] a)
    {
        var o = 0;
        for (int i=1; i<11; i++) {
            var w = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(new Uri(string.Format(a[0]+"&page={0}",i)));
            if(w.GetResponse().ContentLength > 0)
                using(var s = new StreamReader(new GZipStream(w.GetResponse().GetResponseStream(),CompressionMode.Decompress)))
                    foreach(Match m in Regex.Matches(s.ReadToEnd(), @"bounty_amount"":(.+?),"))
                        o += int.Parse(m.Value.Substring(m.Value.IndexOf(':')+1).Replace(",", ""));
        }
        Console.Write(o);
    }
}

Prueba

Tamaño de página predeterminado:

> prog.exe http://api.stackexchange.com/2.2/questions/featured?site=stackoverflow
25300

Tamaño de página = 100:

> prog.exe "http://api.stackexchange.com/2.2/questions/featured?site=stackoverflow&pagesize=100"
37400
jzm
fuente
2

jQuery 191

i=0;function f(p){$.get('//api.stackexchange.com/2.2/questions/featured?site=stackoverflow&page='+p,function(d){for(x in d.items)i+=d.items[x].bounty_amount;d.has_more?f(p+1):alert(i)})};f(1)

Funciona desde cualquier lugar de stackexchange (y muchos otros sitios), no es necesario estar en una página específica como en las respuestas de @ Alconja / @ NateKerkhofs

Einacio
fuente
jQuery es una biblioteca, no un idioma. No estoy seguro si es válido o no ...
rickcnagy 02 de
@ br1ckb0t tómalo como javascript si quieres. jQuery ya está en sitios de intercambio de pila de todos modos, solo estaba siendo explícito sobre el$
Einacio
Sí, eso tiene sentido! Buen código
rickcnagy
2

PHP - 139

Golfizado:

<?php
$a=file_get_contents('http://stackoverflow.com/?tab=featured');preg_match_all('/n">\+([0-9]+)<\/div>/',$a,$r);echo array_sum($r[1]);

Ungolfed - 147

Simple file_get_contents/ preg_match/array_sum

<?php
$a = file_get_contents('http://stackoverflow.com/?tab=featured');
preg_match_all('/n">\+([0-9]+)<\/div>/', $a, $r);
echo array_sum($r[1]);

Prueba:

php run.php

10250

Aziz Saleh
fuente
2

Bash 174

Basado en https://codegolf.stackexchange.com/a/25180/7664 :

s=0;for i in {1..11};do for j in `wget -qO- "stackoverflow.com/questions?pagesize=50&sort=featured&page=$i"|cut -d' ' -f18|egrep '^[0-9]+$'`;do s=$(($s+$j));done;done;echo $s
thejh
fuente
Puede deshacerse de él pagesize=50&y simplemente hacer un bucle más (creo que el tamaño de página predeterminado es 15).
Alconja
@Alconja Hmm, correcto, así que podría reducir esto a 162 ... pero solo con la desventaja de más solicitudes de spam para el servidor.
thejh
2

Python (174 caracteres):

Ampliando la respuesta anterior de Python (no tengo suficiente karma para comentar):

import requests,re;print sum(sum(map(int,re.findall(r"<.*>\+(\d+)<.*>",requests.get("http://stackoverflow.com/questions?sort=featured&page=%u"%i).text)))for i in range(1,33))

Las solicitudes en lugar de urllib reducen en 2 caracteres.

usuario35581
fuente
1

Rubí (176 caracteres):

Siguiendo el ejemplo de Tony H. de usar números de página codificados, esto es lo que obtuve:

require'open-uri';b=0;(1..29).each{|i|d=open("http://stackoverflow.com/questions?sort=featured&page=#{i}").read;b+=d.scan(/<.*>\+(\d+)<.*>/).map{|x|x[0].to_i}.reduce 0,:+};p b

me dio 35300 al momento de escribir.

fotoionizado
fuente