Сколько щедрости на Stackoverflow?

33

Задача:

Вы замечательный программист и отвечающий за Stackoverflow, и вы решаете ответить на каждый вопрос с вознаграждением за Stackoverflow. Вы настолько хороши, что вам удается получить все награды по всем вопросам. В то время как вы ожидаете, что представитель прибудет, вы пишете программу, которая выходит и выясняет, какова общая сумма повторений во всех этих наградах.

Правила:

  • Когда беги,
    • Ваша программа будет перемещаться по избранной вкладке в переполнении стека.
    • Это соскребет ценность каждой награды,
    • Затем он сложит его и покажет общее
  • Он должен загружать данные из любого места на SO (и только на SO), но я бы порекомендовал использовать https://stackoverflow.com/questions?pagesize=50&sort=featured , так как это всего около 10 страниц.
  • Это , поэтому выигрывает самый короткий код
Доктор
источник
32
кашель api.stackexchange.com/docs/featured-questions кашель
bazzargh
2
stackoverflow.com/?tab=featured . Все рекомендуемые вопросы на 1 странице.
Nzall
7
@NateKerkhofs это еще не все. Прокрутите вниз. Например, когда я только что загрузил его, он показывал 96 из 472 вопросов.
Bazzargh
Bounty API
justhalf
@justhalf уже обсуждался ...
TheDoctor

Ответы:

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)

Редактировать 1: обрезать некоторые селекторы и использовать ?:предложение от Google Closure Compiler (через @Sirko - спасибо)

Редактировать 2: инициализировать sвнутриd и инициализировать tкак 0вместо""

Редактировать 3: понял, что на самом деле мне не нужно нацеливаться на конкретный контейнер и я могу смести весь документ, который избавляется от кучки .find вызовов и ненужного селектора (плюс переменная, содержащая его)

Редактировать 4: засунуть t инициализатор в вызов функции, чтобы избежать ;(он все равно будет поднят наверх), и раздвиньте функцию до одного оператора (объедините два оператора в один внутри условия троичного оператора), чтобы удалить{}

Примечание : я не уверен, что это мошенничество, но это должно быть запущено из окна консоли браузера, уже указывающего на http://stackoverflow.com/questions?page=1&sort=featured. Это опирается на тот факт, что JQuery и соответствующие ссылки на пейджинговые ссылки доступны на самой странице. Кроме того, он работает только в Firefox, а не в IE или Chrome.

Вывод (на момент публикации):

38150 (in an alert dialog)

Разнесено / прокомментировано :

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
источник
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 - использовал Google Closure Compiler.
Сирко
8
Подлый выбор языка и контекста, чтобы обойти множество необходимых символов! (Например, " stackoverflow.com/" ) Мне это нравится!
AlexC
Я думаю, вы должны упомянуть, что это делается с помощью плагина jQuery. что я думаю, что это должно быть .. :)
Mr_Green
Chrome выдает синтаксическую ошибку. Открытие функционального тела с (пареном, это действительно работает?
thejh
@Mr_Green - Я уже заметил это, но я выделил это, чтобы привлечь больше внимания ...
Alconja
21

Python - 232, 231, 195, 183, 176174

Разбирает HTML из https://stackoverflow.com/questions?sort=featured с использованием регулярных выражений.

Верхняя граница rangeв forцикл должен бытьnumber of pages + 1 или иначе код вызовет HTTPErrorиз 404 - х. Количество результатов на странице по умолчанию равно 15, что и используется в коде (исключение ?pagesize=50экономит на символах и столь же эффективно).

Благодаря @Gabe за совет по дальнейшему снижению количества символов.

Golfed :

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

Выход (на момент публикации):

37700

Un-golfed :

Вот несколько не играемая в гольф версия, которая должна быть немного легче для чтения и понимания.

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
Вы можете избавиться от явного forцикла и уменьшить его до 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))
Гейб
жестко закодированная верхняя граница затрудняет тестирование
Einacio
2
о боже
wchargin
6
@Richard Да, но это кодовый гольф , так что краткость превосходит, является ли это "хорошей идеей". Я имею в виду, что в реальной жизни также не очень хорошая идея писать ужасные однострочники без пробелов ...
Тим Гудман,
3
@Richard Парсинг html и извлечение из html довольно разные задачи. Так как веб - сайт не является стабильным API, ничего не гарантировано работать для такого рода добычи. Хотя код Тони немного перегружен, поэтому он потерпит неудачу, если будет какой-либо тег, содержащий +после него число. Например, заголовок вопроса может соответствовать этому формату.
CodesInChaos
18

Реболь - 164 133 130 (139 с проверкой 404)

Разбирает HTML, используя parseязык Rebol. Проверяет первые 98 страниц. Я понял, что у меня такое же ограничение, как и у решения на python - слишком много повторов вызывают ошибки 404 и останавливают выполнение. Спасибо @rgchris за множество улучшений! Обновлено, чтобы проверить до 98 страниц.

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

С проверкой ошибок на 404 с (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

Тест

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

объяснение

Rebol игнорирует пробелы, поэтому вы можете поместить все это в одну строку, если захотите. PARSE принимает два входа, и первый аргумент ( read join ...) довольно понятен. Но вот некоторые комментарии к инструкциям разбора диалекта, в более традиционном отступе:

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
источник
Хорошо ... Я добавил обычную отформатированную версию с некоторыми комментариями, надеюсь, вы не против! Всегда приятно видеть, как хорошо Rebol сталкивается с таким количеством проблем с такой грамотностью (все это в кроссплатформенном исполняемом Apache-файле размером в полмегапикселя, но при этом такие вещи, как REFORM, выглядят как больной большой палец. Все остальное имеет смысл, но я все еще смотрю при этом слове и идти "Редукция и превращение ФОРМЫ в РЕФОРМУ" просто безобразно . Одержимость над ним - это очень Хоторн . О, и вы могли бы изменить НЕКОТОРЫЕ на ЛЮБОЕ и сбрить
чарса
К сожалению, должно быть 133.
rgchris
Примечание: вам нужно вернуться к более высокому nзначению ... в настоящее время есть 28 страниц с наградами (для размера страницы 15). Хотя это не повлияет на количество символов.
Alconja
Спасибо Alconja. Легко перейти на 98 страниц, прежде чем добавлять больше символов в решение. Сегодня вечером мне придется повторить тест из дома
Джон
11

Рубин, 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

Использует Stack Exchange API.

Вывод (по состоянию на время исходного поста):

37200

Я не &pagesize=100считаю количество символов, потому что оно работает без него, но я просто добавил это для удобства при тестировании. Если вы удалите это, он сделает то же самое (за исключением того, что съедает больше квоты и занимает немного больше времени).

Дверная ручка
источник
Хорошо, я получил только 275 в Python
Claudiu
ест больше квоты ??? Вы должны были использовать только SO и SO.
Джон Дворжак
@JanDvorak ??? Я имел ввиду квоту API.
Дверная ручка
1
Символ requires можно заменить на -rфлаг командной строки.
Джастин
8

Ребму - 108 107

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

Тест (в 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 выглядит довольно загадочно, но, когда вы освоите его , он станет вполне читабельным. Давайте начнем с того, что размешаем и раскладываем правильно.

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 это диалект Rebol, так что вы можете увидеть сходство в решении. Rebmu пока не может уменьшить размер каждого утверждения, но это развивающийся язык. Еще раз спасибо @rgchris за улучшения моей первой попытки.

johnk
источник
ti (целое число!) будет безопаснее, чем do в Rebmu, без изменения длины кода.
rgchris
6

Рубин - 197

Укороченная версия:

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

Человек дружественная версия:

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

И ответ - 39700

Рубин с параметрами скрипта - 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

Чтобы запустить это из Bash просто введите

ruby code_golf_stack_overflow2.rb http://stackoverflow.com/questions?sort=featured\&page= .bounty-indicator
Cyriel
источник
Символ requires можно заменить на -rфлаг командной строки.
Джастин
6

PHP - 121 байт

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

Использование регулярного выражения 'eval' модификатор, чтобы избежать использования array_sumили аналогичные. Кажется, самое короткое решение среди действительных записей.

Примо
источник
4
eмодификатор был устаревшим PHP 5.5, но это все равно полезно для игры в гольф , тем не менее.
Фабрисио Мате
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;

Будет проходить по всем страницам, pagesizeне будет сохранять байтыGET s.

Очень Очень Грязно, но ... пользуясь PHP"недостатками"!

  • нет места после echo
  • while останавливается на задании
  • выход после RegEx замены является строка, начинающаяся с суммы вознаграждения
  • array_sum() складывает строки
  • $n а также $s инициализируются, но начинать с нуля эквивалентно. как начиная с нуля
  • так далее...
CSᵠ
источник
5

Баш 206

возможна оптимизация, слишком ленив

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

результат:

39450
user19998
источник
4
Я могу ошибаться, но похоже, что это может быть очень коротко с некоторыми качественными оптимизациями.
rickcnagy
seq 1 11может быть уменьшен до seq 11.
Федорки
Вы должны быть в состоянии избавиться от пробелов вокруг труб, чтобы сохранить четыре символа, и, конечно, эти два greps могут быть объединены в один (вы имели в виду "[0-9] +"?).
Desty
Также "grep -o -E" => "egrep -o".
Desty
И вы можете изменить: "egrep -o '[0-9] +'" => "cut -d '' -f3" :)
Desty
5

Javascript - 129 119 110 107 символов

РЕДАКТИРОВАТЬ: НЕДЕЙСТВИТЕЛЬНЫЙ ОТВЕТ! Это обрабатывает только «Популярные вопросы», которые имеют лишь небольшую их часть. Ответ Alconja является более действительным.

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

Выполнить на https://stackoverflow.com/?tab=featured в окне консоли. Основано на решении Alconja.

Гольф это немного больше, удалив ненужные пробелы.

Используется eval для удаления вызова функции, очистки еще 9 символов.

убрал еще несколько ненужных пробелов.

Nzall
источник
3

Ява, 540 символов

Предупреждение: количество активных бонусов составляет ~ 470. Этот код будет обращаться к странице в stackoverflow столько раз. Это может привести к проблемам с ними из-за большого количества запросов данных.

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

Мой вывод был 23400, но когда я запустил код @ TonyH, я получил37550 . Плохие новости.

Красивый код:

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

Это работает просто. Он читает из URL-адреса, http://stackoverflow.com/questions"чтобы определить количество вопросов, которые имеют награды (примечание: если число увеличивается, программа завершается ошибкой, но если она падает, она работает нормально). Он ищет этот номер , используя регулярное выражение: b.>(\\d+). До настоящего времени это работало во всех тестах, но если кто-то задал вопрос, соответствующий этому регулярному выражению, это может не сработать.

Затем мы открываем URL http://stackoverflow.com/questions?pagesize=1&sort=featured&page=+ current question #. Другими словами, мы открываем новую страницу для каждого выбранного вопроса и устанавливаем только количество вопросов 1, чтобы получить их все. Репутация всегда будет совпадать ion.>.(\\d+), поэтому я использую ее, чтобы найти. Я разделил операцию на две части, чтобы я мог дешево проверить, не уменьшилось ли количество вопросов (т.е. возвращаемая строка не является целым числом).

Затем мы суммируем всю репутацию и печатаем ее.

На моей машине потребовалось около 3 минут и 20 секунд.


Кто-нибудь знает, почему он не печатает правильный номер?

Джастин
источник
Pagesize = 100 дает большое число. Я думаю, что происходит что-то странное, потому что вы передаете размер страницы = 1. В моем ответе, если я не указал «размер страницы», результат был близок к вашему номеру.
jzm
@malik Да, я понял, что «неправильно прочитал» ваш комментарий, поэтому я удалил свой :-). размер страницы = 100 действует так, как будто размер страницы = 50. Вы имели в виду, что вы запускали мой код с pageize = 100?
Джастин
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);}}

Использование Stackoverflow.com. То же, что и ниже, за исключением отсутствия распаковки Gzip и другого регулярного выражения.

Тест

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

Странно, получая другое значение, чем ниже.


C # - 496

Это использует api.stackexchange, который является gzipped и 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);}}

Unminified:

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

Тест

Размер страницы по умолчанию:

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

PAGESIZE = 100:

> prog.exe "http://api.stackexchange.com/2.2/questions/featured?site=stackoverflow&pagesize=100"
37400
jzm
источник
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)

Он работает где угодно в stackexchange (и многих других сайтах), нет необходимости находиться на определенной странице, как в @ Alconja / @ NateKerkhofs answers

Einacio
источник
JQuery это библиотека, а не язык. Не уверен, действительно ли это или нет ...
rickcnagy
@ br1ckb0t примите это как javascript, если хотите. В любом случае jQuery уже находится на сайтах для обмена стеками, я просто $
говорил
Да, это имеет смысл! Хороший код
rickcnagy
2

PHP - 139

Golfed:

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

Простой 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]);

Тест:

php run.php

10250

Азиз Салех
источник
2

Баш 174

На основании 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
источник
Вы можете избавиться от pagesize=50&и просто зациклить больше (я думаю, размер страницы по умолчанию, если 15).
Alconja
@Alconja Хмм, верно, так что я смогу довести это до 162 ... но только с обратной стороной большего количества спама на сервер.
thejh
2

Python (174 символа):

Развернемся с ответом Python выше (не хватает кармы, чтобы комментировать):

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

Запросы вместо urllib сокращает 2 символа.

user35581
источник
1

Рубин (176 символов):

Следуя примеру Тони Х. с использованием жестко закодированных номеров страниц, вот что я получил:

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

дал мне 35300 на момент написания.

фотоионизированного
источник