Quanta recompensa existe no Stackoverflow?


33

Tarefa:

Você é um programador incrível e responde a Stackoverflow e decide responder a todas as perguntas com uma recompensa no Stackoverflow. Você é tão bom que consegue obter todas as recompensas em todas as perguntas. Enquanto você espera a chegada do representante, você escreve um programa que descobre qual é a quantidade total de representantes em todas essas recompensas.

Regras:

  • Quando executado,
    • Seu programa irá navegar pela guia em destaque no Stack Overflow.
    • Raspará o valor de cada recompensa,
    • Em seguida, ele será adicionado e exibirá o total
  • Ele precisa baixar dados de qualquer lugar no SO (e somente SO), mas eu recomendo o uso de https://stackoverflow.com/questions?pagesize=50&sort=featured , pois são apenas 10 páginas
  • Isso é , então o código mais curto vence


2
stackoverflow.com/?tab=featured . Todas as perguntas em destaque em 1 página.
Nzall #

7
@NateKerkhofs não são todos eles. Role para baixo. por exemplo, quando carreguei, estava mostrando 96 de 472 perguntas.
bazzargh


@justhalf já foi discutido ...
TheDoctor

Respostas:


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)

Edição 1: reduziu alguns seletores e usou a ?:sugestão do Closure Compiler do Google (via @Sirko - obrigado)

Editar 2: inicialize sdentro de inicialize tcomo em 0vez de""

Edição 3: percebi que não preciso segmentar um contêiner específico e posso varrer todo o documento, o que elimina várias .findchamadas e um seletor desnecessário (além da variável que o contém)

Editar 4: empurre o tinicializador na chamada de função para evitar um ;(ele será içado para o topo de qualquer maneira) e esmague a função em uma instrução (combine duas instruções em uma dentro da condição de instrução ternária) para soltar o{}

Nota : Não tenho certeza se está trapaceando, mas isso deve ser executado a partir da janela do console de um navegador que já está apontando http://stackoverflow.com/questions?page=1&sort=featured. Ele se baseia no fato de que o jQuery e os links de paginação apropriados estão disponíveis na própria página. Além disso, ele parece funcionar apenas no Firefox e não no IE ou Chrome.

Saída (no momento da postagem):

38150 (in an alert dialog)

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

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 - usado Google Closure Compiler.
Sirko

8
Escolha sorrateira de linguagem e contexto para ignorar muitos dos caracteres necessários! (Como " stackoverflow.com/" ) Gostei!
AlexC

Eu acho que você deve mencionar que isso é feito usando o plugin jQuery. que eu acho que deveria ser .. :)
Mr_Green

O Chrome lança um erro de sintaxe. Abrir um corpo funcional com (parênteses, isso realmente funciona?
thejh

@Mr_Green - Já notou que, mas eu tenho em negrito para chamar mais a atenção ...
Alconja

21

Python - 232, 231, 195, 183, 176, 174

Analisa o HTML em https://stackoverflow.com/questions?sort=featured usando expressões regulares.

O limite superior rangedo forloop deve ser number of pages + 1ou o código aumentará HTTPErrordevido a 404s. O número padrão de resultados por página é 15, que é o que o código usa (omitir ?pagesize=50economiza em caracteres e é igualmente eficaz).

Agradecemos a @Gabe pela dica sobre como reduzir ainda mais a contagem de caracteres.

Golfe :

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

Saída (no momento da postagem):

37700

Sem golfe :

Aqui está uma versão não-golfe que deve ser um pouco mais fácil de ler e entender.

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

1
Você pode se livrar do forloop explícito e reduzi-lo para 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

Tendo um hardcoded marcas limite superior um pouco difícil de teste
Einacio


6
@ Richard Sim, mas isso é código de golfe , então a brevidade supera se é uma "boa idéia". Quer dizer, na vida real, também não é uma boa idéia para escrever one-liners horrendos com nenhum espaço em branco ...
Tim Goodman

3
@ Richard Parsing html e extração de html são tarefas bem diferentes. Como um site não é uma API estável, nada garante que funcione para esse tipo de extração. Embora o código de Tony seja um pouco exagerado, ele falharia se houvesse alguma tag contendo uma +seguida por um número. Por exemplo, um título de pergunta pode se encaixar nesse formato.
CodesInChaos

18

Rebol - 164 133 130 (139 com verificação 404)

Analisa o html usando o parsesub-idioma do Rebol. Verifica as primeiras 98 páginas. Percebi que tenho a mesma restrição que a solução python - muitas repetições atingem erros 404 e interrompem a execução. Obrigado a @rgchris por muitas melhorias! Atualizado para verificar até 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

Com verificação de erro 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

Teste

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

Explicação

Rebol ignora o espaço em branco, portanto, você pode colocar tudo em uma linha como essa, se quiser. O PARSE recebe duas entradas e o primeiro argumento ( read join ...) é bastante auto-explicativo. Mas aqui estão alguns comentários sobre as instruções do dialeto de análise, em um recuo mais 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

Bom ... Eu adicionei uma versão formatada oridinary com alguns comentários, espero que você não se importe! É sempre bom ver o quão bem o Rebol resolve tantos problemas com essa alfabetização (tudo em um executável licenciado pela Apache de meia-plataforma, mas que faz coisas como REFORM se destacarem como um dedão dolorido. Todo outro pedaço faz sentido, mas ainda pareço nessa palavra e diga "Reduzir e formar sendo transformado em reforma" é simplesmente feio . A obsessão por isso é muito Hawthorne . Ah, e você pode mudar ALGUNS para QUALQUER e raspar um caractere! :-)
Dr. Rebmu

Opa, deve ser 133.
rgchris

Nota: Você precisa fazer um loop para um nvalor mais alto ... atualmente existem 28 páginas de recompensas (para o tamanho da página 15). Não afetará sua contagem de caracteres.
Alconja

Obrigado Alconja. Fácil de subir até 98 páginas antes de adicionar mais caracteres à solução. Vou ter que re-executar o teste em casa esta noite
johnk

11

Ruby, 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

Usa a API do Stack Exchange.

Saída (a partir do momento da postagem original):

37200

Não estou contando a contagem de &pagesize=100caracteres, porque funciona sem ele, mas acrescentei isso por conveniência durante o teste. Se você remover isso, ele faz a mesma coisa (exceto que consome mais cota e demora um pouco mais).


Bom, eu só tenho que 275 em Python
Claudiu

come mais cota ??? Você deveria usar apenas SO e SO.
John Dvorak

@JanDvorak ??? Eu quis dizer cota de API.
Maçaneta

1
Os requires podem ser substituídos pelo -rsinalizador de linha de comando.
Justin

8

Rebmu - 108 107

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

Teste (às 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 um tanto enigmático, mas é bastante legível quando você pega o jeito. Vamos começar a silenciá-lo e colocá-lo adequadamente.

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 é um dialeto da Rebol, para que você possa ver as semelhanças na solução. Rebmu ainda não pode reduzir o tamanho de todas as declarações, mas é uma linguagem em evolução. Agradeço novamente a @rgchris pelas melhorias na minha primeira tentativa.


ti(para inteiro!) seria mais seguro do que dono Rebmu sem alteração no comprimento do código.
Rogchris #

6

Ruby - 197

Versão curta:

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

Versão amigável para 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

E responda - 39700

Ruby com 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 executar isso no bash, digite

ruby code_golf_stack_overflow2.rb http://stackoverflow.com/questions?sort=featured\&page= .bounty-indicator

Os requires podem ser substituídos pelo -rsinalizador de linha 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 um modificador 'eval' do regex, para evitar o uso array_sumou similar. Parece ser a solução mais curta entre entradas válidas.


4
o emodificador foi descontinuado no PHP 5.5, mas ainda assim é útil para jogar golfe.
Fabrício Matté 03/04

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;

Irá percorrer todas as páginas, pagesizenão está definido para salvar bytes, portanto mais GETs.

Muito, muito sujo, mas ... aproveitando PHPas "falhas" de!

  • sem espaço depois echo
  • while para na atribuição
  • a saída após a RegExsubstituição é uma sequência que começa com o valor da recompensa
  • array_sum() adiciona cordas
  • $ne $ssão inicializados, mas a partir do nada é equivalente. como começando do zero
  • etc ...

5

Bash 206

otimizações possíveis, com preguiça

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

4
Eu posso estar errado, mas isso pode parecer muito curto com algumas otimizações de qualidade.
Rickcnagy

seq 1 11pode ser reduzido para seq 11.
Fedorqui 2/04

Você deve conseguir se livrar dos espaços ao redor dos tubos para salvar quatro caracteres, e certamente esses dois greps podem ser mesclados em um (você quis dizer "[0-9] +"?).
Destino

Também "grep -o -E" => "egrep -o".
Desty

E você pode alterar: "egrep -o '[0-9] +'" => "cortar -d '' -f3" :)
Desty

5

Javascript - 129 119 110 107 caracteres

EDIT: RESPOSTA INVÁLIDA! Isso lida apenas com as "Principais perguntas em destaque", que possuem apenas uma fração delas. A resposta de Alconja é mais válida.

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

Execute em https://stackoverflow.com/?tab=featured em uma janela do console. Baseado na solução da Alconja.

Jogou um pouco mais com a remoção de espaços em branco desnecessários.

Eval usado para remover a chamada de função, limpando outros 9 caracteres.

limpou um espaço em branco mais desnecessário.


3

Java, 540 caracteres

Aviso: o número de recompensas ativas é ~ 470. Este código acessará uma página no stackoverflow tantas vezes. Você pode ter problemas com eles por fazer tantas solicitações de dados.

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

Minha saída foi 23400, mas quando corri o código do @ TonyH, obtive 37550. Más notícias.

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

A maneira como isso funciona é simples. Ele lê a URL http://stackoverflow.com/questions"para determinar o número de perguntas que têm recompensas (nota: se o número aumentar, o programa falhará, mas se cair, funcionará bem). Ele procura por este número usando a regex: b.>(\\d+). Isso funcionou em todos os testes até o momento, mas se alguém fez uma pergunta que corresponda a essa expressão regular, isso pode não funcionar.

Então, abrimos o URL http://stackoverflow.com/questions?pagesize=1&sort=featured&page=+ current question #. Em outras palavras, abrimos uma nova página para cada pergunta em destaque e forçamos o número de perguntas a serem apenas 1, para obter todas elas. A parte da reputação sempre corresponderá ion.>.(\\d+), então eu a uso para encontrá-la. Dividi a operação em duas partes, para que eu pudesse verificar de forma barata se o número de perguntas reduziu (ou seja, a sequência retornada não é um número inteiro).

Em seguida, resumimos toda a reputação e a imprimimos.

Demorou cerca de 3 minutos e 20 segundos para rodar na minha máquina.


Alguém sabe por que não está imprimindo o número certo?


tamanho da página = 100 fornece o número grande. Eu acho que algo estranho está acontecendo porque você está passando o tamanho da página = 1. Na minha resposta, se eu não especificasse 'tamanho da página', o resultado seria próximo ao seu número.
JZM

@ Malik Sim, eu percebi que "interpretei mal" o seu comentário, então excluí o meu :-). tamanho da página = 100 atua como se tamanho da página = 50. Você quis dizer que executou meu código com tamanho da página = 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. O mesmo que abaixo, exceto que não há descompactação do Gzip e regex diferente.

Teste

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

Estranhamente, obtendo um valor diferente do que abaixo.


C # - 496

Isso usa api.stackexchange, que é compactado com gzip e 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);}}

Desminificado:

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

Teste

Tamanho da página padrão:

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

Tamanho da página = 100:

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

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 de qualquer lugar no stackexchange (e em muitos outros sites), não precisa estar em uma página específica, como nas respostas @ Alconja / @ NateKerkhofs


O jQuery é uma biblioteca, não uma linguagem. Não tenho certeza se é válido ou não ...
rickcnagy

@ br1ckb0t tomá-lo como javascript, se quiser. jQuery já está em sites Stackexchange de qualquer maneira, eu estava apenas sendo explícito sobre a$
Einacio

Sim, isso faz sentido! Código legal.
Rickcnagy

2

PHP - 139

Golfe:

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

Sem Golfe - 147

Simples 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]);

Teste:

php run.php

10250


2

Bash 174

Com base em 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

Você pode se livrar do pagesize=50&e apenas fazer um loop mais (acho que o tamanho da página padrão se 15).
Alconja

@ Alconja Hmm, certo, então eu poderia reduzir isso para 162 ... mas apenas com a desvantagem de mais solicitações de spam para o servidor.
thejh

2

Python (174 caracteres):

Expandindo a resposta python acima (não há carma suficiente 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))

Pedidos em vez de urllib reduzem 2 caracteres.


1

Ruby (176 caracteres):

Seguindo o exemplo de Tony H. de usar números de página codificados, aqui está o que eu tenho:

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 deu 35300 no momento em que escrevi.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.