Скільки виграшів на Stackoverflow?


33

Завдання:

Ви дивовижний програміст і Stackoverflow-Answerer, і ви вирішили відповісти на кожне запитання щедро на Stackoverflow. Ви настільки хороші, що вам вдається отримати всі принади у всіх питаннях. Поки ви чекаєте, поки представник заллється, ви пишете програму, яка йде і дізнається, яка загальна кількість представників у всіх цих щедротах.

Правила:

  • Під час запуску,
    • Ваша програма буде переходити через представлені вкладки на "Переповнення стека".
    • Це викреслить вартість кожної виграші,
    • Потім він додасть його та відобразить загальну суму
  • Він повинен завантажувати дані з будь-якого місця на SO (і тільки SO), але я б рекомендував використовувати https://stackoverflow.com/questions?pagesize=50&sort=featured , оскільки це лише близько 10 сторінок
  • Це , тому виграє найкоротший код


2
stackoverflow.com/?tab=featured . Усі пропоновані питання на 1 сторінці.
Nzall

7
@NateKerkhofs - це ще не все. Прокрутіть донизу. наприклад, коли я тільки завантажував його, він показував 96 із 472 питань.
bazzargh


@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 (через @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)

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.
Сірко

8
Підлий вибір мови та контексту, щоб обійти безліч потрібних символів! (Наприклад, " stackoverflow.com/" ) Мені це подобається!
AlexC

Я думаю, ви повинні згадати, що це робиться за допомогою плагіна jQuery. що я думаю, що повинно бути .. :)
Mr_Green

Chrome видає синтаксичну помилку. Відкриваючи функціональний орган з (батьком, чи справді це працює?
thejh

@Mr_Green - Я вже це зазначив, але я
виділив це сміливістю,

21

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

Розбирає HTML з https://stackoverflow.com/questions?sort=featured, використовуючи регулярні вирази.

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

Дякуємо @Gabe за пораду щодо ще більшого зменшення кількості чар.

Гольф :

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

Без гольфу :

Ось дещо не гольф-версія, яку слід трохи простіше читати та розуміти.

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))
Гейб

наявність
твердо кодованої


6
@Richard Так, але це кодовий гольф , тому стислість козиряє, чи це "гарна ідея". Я маю на увазі, що в реальному житті також не дуже гарна ідея писати жахливі однолитки без пробілів ...
Тім Гудмен

3
@ Richard Parsing 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

Приємно ... Я додав оригінальну відформатовану версію з деякими коментарями, сподіваюся, ви не заперечуєте! Завжди чудово бачити, наскільки добре Rebol нігтів так багато проблем з такою грамотністю (все це на півмісячного крос-платформного виконавчого коду, який має ліцензію Apache, але це означає, що такі речі, як REFORM, стикаються, як болісний палець. Кожен інший біт має сенс, але я все одно дивлюся в цьому слові і піти "Збавитись, і ФОРМА перетвориться на РЕФОРМУ" просто некрасиво . Нав'язливість над нею є дуже Готорн . О, і ти міг би змінити
ДЕЙЧОГО на КОГО-небудь і відголити чару

На жаль, має бути 133.
rgchris

Примітка. Вам потрібно зробити цикл на більш високе nзначення ... на даний момент 28 сторінок баунті (для розміру сторінки 15). Хоча це не вплине на вашу кількість графіка.
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

Використовується API обміну стеками.

Вихід (за часом початкової публікації):

37200

Я не рахую &pagesize=100кількість символів, тому що вона працює без неї, але я просто додала це для зручності під час тестування. Якщо ви вилучите це, це зробить те ж саме (за винятком того, що він з'їдає більше квот і займає трохи більше часу).


Приємно, я отримав це лише до 275 року в Python
Клавдіу

їсть більше квоти ??? Ви повинні були використовувати лише 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

Ребму виглядає доволі виразним , але він є досить читабельним, як тільки ви знайдете його. Почнемо з розмивання і належним чином.

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 поки не може зменшити розмір кожного твердження, але це мова, що розвивається. Ще раз дякую @rgchris за покращення моєї першої спроби.


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

Ruby з параметрами сценарію - 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

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, але це все одно корисно для гри в гольф , тим не менш.
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;

Буде проглядати всі сторінки, pagesizeне встановлено для збереження байтів, тому більше GETs.

Дуже дуже брудно, але ... скориставшись PHP"недоліками"!

  • немає місця після echo
  • while зупиняється при призначенні
  • вихід після RegExзаміни - це рядок, що починається з суми баунті
  • array_sum() додає рядки
  • $n і $s ініціалізуються, але починаючи з нічого не еквівалентно. як починаючи з нуля
  • тощо ...

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

4
Я можу помилятися, але, схоже, це може бути дуже коротким із деякими оптимізаціями якості.
rickcnagy

seq 1 11можна звести до seq 11.
fedorqui

Ви повинні мати можливість позбутися пробілів навколо труб, щоб зберегти чотири символи, і, безумовно, ці два грепи можна об'єднати в одну (ви мали на увазі "[0-9] +"?).
Desty

Також "grep -o -E" => "egrep -o".
Десті

І ви можете змінити: "egrep -o" [0-9] + '"=>" cut -d' '-f3 ":)
Desty

5

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

РЕДАКТУЙТЕ: НЕВЕРИДНИЙ ВІДПОВІДЬ! Це стосується лише "Найпопулярніших питань", у яких є лише їхня частина. Відповідь Алконджі є більш достовірною.

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

Виконати на https://stackoverflow.com/?tab=featured у консольному вікні. На основі рішення Alconja.

Полювали його трохи більше, видаливши зайві пробіли.

Використовується eval для видалення виклику функції, очищення ще 9 символів.

очистили ще небажаний пробіл.


3

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

Попередження: кількість активних щедротів становить ~ 470. Цей код буде отримувати доступ до сторінки в потоковому потоці багато разів. Це може створити вам проблеми з ними, оскільки вони роблять так багато запитів даних.

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 секунд.


Хтось знає, чому він не друкує потрібний номер?


pageize = 100 дає велику кількість. Я думаю, що щось дивне відбувається, тому що ти передаєш розмір сторінки = 1. У своїй відповіді, якщо я не вказав "розмір сторінки", результат був близький до вашого номера.
jzm

@malik Так, я зрозумів, що "перечитав" ваш коментар, тому видалив мою :-). pageize = 100 діє так, ніби сторінкуize = 50. Ви мали на увазі, що ви запустили мій код із розміром сторінки = 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);}}

Без обмежень:

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

Розмір сторінок = 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)

Він працює з будь-якого місця stackexchange (та багатьох інших сайтів), не потрібно знаходитись на певній сторінці, як у відповідях @ Alconja / @ NateKerkhofs


jQuery - це бібліотека, а не мова. Не впевнений, чи дійсний він чи ні ...
rickcnagy

@ br1ckb0t, якщо ви хочете, прийміть це як JavaScript. jQuery у будь-якому разі вже є на сайтах stackexchange, я просто $
роз'ясняв

Так, це має сенс! Хороший код.
rickcnagy

2

PHP - 139

Гольф:

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

Безголів - 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

You can get rid of the pagesize=50& and just loop more (I think the default page size if 15).
Alconja

@Alconja Hmm, right, so I could get this down to 162... but only with the downside of more request spam to the server.
thejh

2

Python (174 characters):

Expanding on the python answer above (don't have enough karma to comment):

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

Requests in lieu of urllib cuts down on 2 chars.


1

Ruby (176 chars):

Following Tony H.'s example of using hard-coded page numbers, here's what I got:

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

gave me 35300 at the time of writing.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.