Скільки виграшів на 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.