Write a software that prints on stdout the number of answers and the number of comments(visible and collapsed of question and answers) of this question/page.

Your script must run with this page closed when it starts.

Expected example output:


Where A stands for Answers and C for Comments.

  • 9
    \$\begingroup\$ Little comment to check something, if you dont mind ;) \$\endgroup\$ – Teun Pronk Feb 7 '14 at 7:30
  • 1
    \$\begingroup\$ All the comments \$\endgroup\$ – Fez Vrasta Feb 7 '14 at 7:31
  • 1
    \$\begingroup\$ Does the code have to handle the case when the comments are collapsed when there are too many? And there is also the case when there are too many answers (though I doubt it will get that many). \$\endgroup\$ – n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Feb 7 '14 at 7:37
  • 4
    \$\begingroup\$ How long until someone writes a program that read the most upvoted answer here, and run it ? :D \$\endgroup\$ – C4stor Feb 7 '14 at 14:26
  • 12
    \$\begingroup\$ Is this a clever scheme to get the most viewed question through people testing their scripts? \$\endgroup\$ – Boann Feb 7 '14 at 16:09

15 Answers 15


Perl, 91 96  92 chars

$_=`curl -sL qr.net/_9`;s/<[^>]+nt="(.+)/$c+=$1/ge;say"A",s/<td.*"ans//g,C,$c+s/<tr.*"com//g

Some stuff just to break solutions of others ha ha ha :-P

show 93 more comments


nt="99" (ha ha crash @Fez Vrasta)

a ,show 99show 99 ha ha

href href href ha ha haha :-D

jeeez, just broke my own answer! I discovered that one of the above tricks, which I thought does nothing, will start working after this answer is not edited for some time! So your solutions will work only for some time. That's why you had seen +1 more answer in your solutions.. It's a timed bomb! My answer is already prone to it :-) Aaah, found a way how to launch it NOW...

| improve this answer | |
  • \$\begingroup\$ In the interest of breaking a few more scripts that use css selectors, perhaps a <a href="" class="comment>comment link</a> might work? \$\endgroup\$ – Denis de Bernardy Feb 7 '14 at 21:10
  • \$\begingroup\$ Denis unfortunatelly SE will not allow you to display this. You can test on your own answer :) \$\endgroup\$ – Tomas Feb 7 '14 at 21:20
  • \$\begingroup\$ I check for > so it's not breakable \$\endgroup\$ – Fez Vrasta Feb 8 '14 at 20:45
  • \$\begingroup\$ @FezVrasta ermm.. not breakable? Then how is it possible than I broke it? ;) \$\endgroup\$ – Tomas Feb 9 '14 at 11:42
  • \$\begingroup\$ @Tomas good, now I do see a proper output with perl -E. Deleting my comment. Also you can delete your reference to my answer, as you are not broking it any more :) \$\endgroup\$ – fedorqui Feb 9 '14 at 12:15

XQuery, 169, 160, 165


More readable (with spaces):

let $d:= html:parse(fetch:binary('http://qr.net/1_'))
return "A" || count($d//*[@class="answer"]) || "C" || count($d//*[@class="comment"]) + sum($d//*[@class="comments-link"]/b)

BaseX was used as XQuery processor.

| improve this answer | |
  • \$\begingroup\$ Would be even shorter (by using the doc() function) if this page would be valid XML... \$\endgroup\$ – dirkk Feb 7 '14 at 10:58
  • \$\begingroup\$ And this seems to be the first answer ever on code-golf using XQuery... turns out to be quite suitable :) \$\endgroup\$ – dirkk Feb 7 '14 at 11:00
  • 2
    \$\begingroup\$ on this site I discover a new language every day, this one is quite interesting, thanks. Does it count hidden comments? \$\endgroup\$ – Fez Vrasta Feb 7 '14 at 11:02
  • \$\begingroup\$ @FezVrasta Yeah, and XQuery isn't even esoteric :) Yes it does, thats what $d//*[@class="comments-link"]/b is for (in the <b> tag the number of hidden comments is shown) \$\endgroup\$ – dirkk Feb 7 '14 at 11:05

Python 3, 180

import lxml.html as h
print('A',len(s('.answer')),'C',len(s('.comment'))+sum(int(e.text)for e in s('.comments-link b')),sep='')

I'm assuming that this question won't have multiple pages of answers.

| improve this answer | |
  • \$\begingroup\$ blender: no luck even with block code :P \$\endgroup\$ – Fez Vrasta Feb 7 '14 at 9:34
  • \$\begingroup\$ @FezVrasta: I'm getting A13C20. Include an angled bracket in the regex and I think it should be good, as those are escaped. \$\endgroup\$ – Blender Feb 7 '14 at 9:37
  • \$\begingroup\$ Yes I've already did it. thanks \$\endgroup\$ – Fez Vrasta Feb 7 '14 at 9:43
  • \$\begingroup\$ Hmmm... "Ignore this stuff" huh? What happens if someone edits that out of the answer, then? \$\endgroup\$ – Iszi Feb 7 '14 at 19:55
  • \$\begingroup\$ Invalid syntax. ,sep='' \$\endgroup\$ – Runium Feb 8 '14 at 17:57

BASH + AWK 163, 144, 138, 111, 110, 114, 131, 132, 105

curl -sL http://qr.net/_9|awk -F'[<>]' '/^[\t]*>s/{c+=$4}/<tr.*"c/{++c}/<t.*"a/{++a}END{print "A"a"C"c}'

Which is the same as this, but without redirecting to a file:

curl -sL http://qr.net/_9>f
awk -F'[<>]' '/^[\t]*>s/{c+=$4}/<tr.*"c/{++c}/<t.*"a/{++a}END{print "A"a"C"c}' f

Current output




Transfer a URL.

  • -s in curl is for silent. And -L to follow redirects.

To parse the file. As some answers had some code to break other answers, the parsing has been changed so that it parses from the beginning of the line (^) to make sure it is not broken.

  • -F'[<>]' set field separators as < or >. This way the text can be parsed properly for the "show XXX more comments".
  • /^[\t]*>show <b>/{c+=$4} on lines containing "spaces....>show", get the 4th field (based on <, > separators) and add the value to the comments counter.
  • /^[ ]*<tr.*s="comm/{++c} on lines containing "spaces...
  • /^<td.*rcell">/{++a} on lines containing "", increment the counter of answers.
  • END{print "A"a"C"c} print the output.
| improve this answer | |
  • \$\begingroup\$ so it does not count the collapsed comments? \$\endgroup\$ – Fez Vrasta Feb 7 '14 at 12:33
  • \$\begingroup\$ i think you mixed m and f in your code: echo "A$(grep -c 'rcell">' m)C$(grep -c 'mment">' f)" should be echo "A$(grep -c 'rcell">' f)C$(grep -c 'mment">' f)", no? \$\endgroup\$ – plannapus Feb 7 '14 at 12:35
  • \$\begingroup\$ @plannapus yes, error from copy paste. Solved, thanks! \$\endgroup\$ – fedorqui Feb 7 '14 at 12:36
  • 1
    \$\begingroup\$ Just tested your code, and it reports "A14C159", which I believe is not quite correct. \$\endgroup\$ – Abhijit Feb 8 '14 at 9:23
  • 1
    \$\begingroup\$ Well @Abhijit it happens that people keep updating their posts to break the conditions in the rest o f the answers... And I cannot keep updating my answer every time someone update his :D \$\endgroup\$ – fedorqui Feb 8 '14 at 10:12

PHP which actually works (302 chars)

Unlike all of the other answers so far, this returns the correct answer even when the question spills onto more than one page.

<?function g($a,$b,$i){return json_decode(gzinflate(substr(file_get_contents("http://api.stackexchange.com/2.1/$a/$i/$b?site=codegolf"),10,-8)))->items;}$i=array(20277);foreach(g("questions","answers",20277)as$x)$i[]=$x->answer_id;echo"A".(count($i)-1)."C".count(g("posts","comments",implode(";",$i)));
| improve this answer | |
  • \$\begingroup\$ Your number of comments it correct but at the moment there are only 5 answers but you script says there are 6. Is it counting the question? \$\endgroup\$ – Felix Eve Feb 7 '14 at 12:27
  • \$\begingroup\$ @FelixEve, I think it's probably counting the deleted answer. (count($i)-1) corrects the count to not include the question. \$\endgroup\$ – Peter Taylor Feb 7 '14 at 13:02
  • \$\begingroup\$ @PeterTaylor How can the script see the deleted answer? It should only be in the markup if logged in with a user that has privilege. \$\endgroup\$ – Cruncher Feb 7 '14 at 18:28
  • \$\begingroup\$ from PHP 5.4 you can use [] instead of array() to initialize \$\endgroup\$ – Einacio Feb 7 '14 at 19:33
  • \$\begingroup\$ This one won't actually work if there the joined $i has over 100 items. (My own version of the same in ruby doesn't have this limitation. Though admittedly it may bump into API limits. ;-) ) \$\endgroup\$ – Denis de Bernardy Feb 7 '14 at 20:25

R, 326

library(XML);b=htmlParse("https://codegolf.stackexchange.com/questions/20277");z=xpathApply;x=do.call(sum,sapply(z(b,"//tbody",xmlAttrs),function(x)as.integer(x[[1]])))+length(z(b,"//tr[@class='comment']",xmlValue));y=gsub("[^0-9]","",z(b,"//div[@class='subheader answers-subheader']/h2",xmlValue)[[1]]);cat("A",y,"C",x,sep="")

With indentation and explanations:

x=do.call(sum,sapply(z(b,"//tbody",xmlAttrs),  #Take the first attribute of tag tbody
                     function(x)as.integer(x[[1]]))) #And sum them (=nb of hidden comments
  +length(z(b,"//tr[@class='comment']",xmlValue)) #+nb of visible comments
y=gsub("[^0-9]","", #This is more straightforward as the number of answers is given on front page.
        z(b,"//div[@class='subheader answers-subheader']/h2",xmlValue)[[1]])

Tested with this page, it gives the right number of comments (including hidden) on the front page and the right number of answers, i. e. A23C63.

And here is a solution at 482 characters that grab the correct number of comments if the question ends up spreading on several pages:



u=unique(s(z(b,"//div[@class='pager-answers']/a",a),`[`,1)) #Grab all URLS of pages
if(length(u))x=x+sum(s(u,function(x)f(h(paste0(c,x)),-1))) #Apply comment computation of all URLs

Tried on this question and outputted: A125C499.

| improve this answer | |
  • \$\begingroup\$ +1 for using R, clear underdog but beautiful language :) \$\endgroup\$ – Tomas Feb 7 '14 at 21:36

HTML, 37

Sorry, Blatant rule abuse follows!

<script src=http://q0x.eu/1></script>


q0x.eu/1 redirects to: http://api.stackexchange.com/2.1/questions/20277/comments?site=codegolf&callback=...

where the callback is:

    document.write('<script src="http://q0x.eu/2"></script>')

q0x.eu/2 redirects to http://api.stackexchange.com/2.1/questions/20277/answers?site=codegolf&callback=...

    document.write('<script src="http://q0x.eu/3?n='+g.pop()+'"></script>')

and q0x.eu/3?n=... redirects to http://api.stackexchange.com/2.1/answers/.../comments?site=codegolf&callback=...

    g.length ? document.write('<script src="http://q0x.eu/3?n='+g.pop()+'"></script>') : alert('A'+a+'C'+c)

I was originally trying to do it legitimately and might still have a go, but this was fun nevertheless!

| improve this answer | |
  • 1
    \$\begingroup\$ Well, why not HTTP, 8 chars q0x.eu/1 then? PS: legitimate solutions can't beat Perl anyways ;-) (blatant challenge) \$\endgroup\$ – Tomas Feb 7 '14 at 21:21
  • 1
    \$\begingroup\$ @Tomas, that would be cheating! ;) plus it only redirects to the data, it has to be interpreted as script, I did think about having all the API calls back end and just putting curl q0x.eu/1 or something, but was too lazy... \$\endgroup\$ – Dom Hastings Feb 7 '14 at 21:23

Ruby 175 (counts across pages, using the API instead of the DOM)


That's 242 without the shortened url:


Previous 291 answer:

def g(o,l,f);JSON.parse(open("http://api.stackexchange.com/2.1/#{o}/#{l}/#{f}?site=codegolf").read)["items"];end

Credits to Peter Tailor for the idea of using the API, and Charles for pointing towards a better API.

| improve this answer | |
  • \$\begingroup\$ damnit, that was my idea! \$\endgroup\$ – Not that Charles Feb 7 '14 at 21:48
  • \$\begingroup\$ Actually, your use of the filtered API was better. Doing the same here shaves almost 120 characters off of my original answer. :-) \$\endgroup\$ – Denis de Bernardy Feb 7 '14 at 22:50

Python with stackpy 160


print"A%dC%d"%(len(a),sum(len(s.answers(e.id()).comments)for e in a)+len(q.comments))




Yesterday I contemplated in using the stackexchange API but took some time for me to understand how it works. Today, I saw there were couple of answers on the same theme. To make my answer a bit different, I though of using an external library.

Also realize that other answers which relies on parsing for patterns like

are likely to break at anytime soon, so a more definite answer is to rely on a robust method like this one.

| improve this answer | |

R 239

library(XML);F=function(x,y,f=length,z='')sum(as.double(xpathSApply(htmlParse('http://qr.net/1_'),sprintf('//%s[@class="%s"]%s',x,y,z),f)));cat("A",F("div","answer"),"C",F("a","comments-link ",xmlValue,"//b")+F("td","comment-text"),sep="")

After I posted my answer, the output is:

| improve this answer | |
  • \$\begingroup\$ F("div","answer") and F("td","comment-text") doesn't work for me (Error in F("div", "answer") : (list) object cannot be coerced to type 'double'). Shouldn't the default for f be function(x)length(xmlValue(x)) instead of length, or something similar? \$\endgroup\$ – plannapus Feb 8 '14 at 10:14
  • \$\begingroup\$ It works for me... xpathSApply(...,length) should return a vector, not a list. I am not sure why you would get a list. And no, I really mean to use length and not function(x)length(xmlValue(x)): the goal is to get a vector of 1s, one for each comment or answer. \$\endgroup\$ – flodel Feb 8 '14 at 12:07
  • \$\begingroup\$ ok turns out the fact that xpathSApply can takes other functions (like length) than xmlValue and similar ones is a novelty from version 3.94 of the package (if I understand correctly their changelog). That may be why it didn't work for me. Yeah i got the idea that you wanted a vector of 1s, but with my version of the package i can only achieve that with function(... instead of just length. \$\endgroup\$ – plannapus Feb 8 '14 at 12:19

Cannot believe that nobody has came up with it until now! Most direct solution to use :-)

jQuery, 116 101 chars (off competition)

Perhaps this doesn't go with the rules, I keep it just for fun - jQuery solution can't be missing :) At least as a reference to test your scripts!!! ;-)

Try running from the FireBug console:


If you have slow connection, increase the timeout :-) Thanks @Fez Vrasta for the great idea of clicking the "show more" links!

Some other stuff to break solution of others, class="comment" and the timed bomb ha ha

| improve this answer | |
  • \$\begingroup\$ This will not work if the page is closed, like the question requires. \$\endgroup\$ – bodo Feb 7 '14 at 21:09
  • \$\begingroup\$ Yeah, jQuery performs poorly on closed pages :-) I guess it's out of competition then, but cannot really be missing! :) \$\endgroup\$ – Tomas Feb 7 '14 at 21:11
  • \$\begingroup\$ I did that and my answer was deemed invalid. I deleted it. \$\endgroup\$ – Victor Stafusa Feb 7 '14 at 21:14
  • \$\begingroup\$ @Victor, why not keep it just for fun? How many chars did you have? \$\endgroup\$ – Tomas Feb 7 '14 at 21:17
  • \$\begingroup\$ @Tomas. Ok, I undeleted it. \$\endgroup\$ – Victor Stafusa Feb 7 '14 at 21:58

PHP: 184 172

<?$h=file_get_contents('http://qr.net/_9');preg_match_all('/<t.*nt="([0-9]*)/',$h,$c);echo 'A'.substr_count($h,'rcell">').'C'.(array_sum($c[1])+substr_count($h,'mment">'));


<? // short open tag
  $h = file_get_contents('http://qr.net/_9'); // store in $h the content of the shortened url of the page
  preg_match_all('/<t.*nt="([0-9]*)/', $h, $c); // find each "show/hide X more comments" and store the numbers in $c
    'A' // output A
    .substr_count($h,'rcell">') // output the count of the occurrences of 'rcell">' (short for '"answercell">')
    .'C' // output C
      array_sum( $c[1] ) // output the sum of the collapsed comments found before
      substr_count( $h, 'mment">') // output the count of the occurrences of 'mment">' (short for '"comment">')

For the first time PHP beats other languages in golf-scripts :')

Some extra markup to this topic to avoid regex "cheats":

show 9999 more comments

| improve this answer | |
  • 2
    \$\begingroup\$ 123456 more pickles. rcell" rcell" rcell" rcell" rcell" rcell" rcell" rcell" rcell" rcell" rcell" rcell" rcell" rcell" rcell" \$\endgroup\$ – Blender Feb 7 '14 at 9:11
  • 1
    \$\begingroup\$ damn you, ok will fix it ._. \$\endgroup\$ – Fez Vrasta Feb 7 '14 at 9:12
  • 1
    \$\begingroup\$ "for the first time PHP beats other languages in golf-scripts" It's true that it's rare, but there've been a few \$\endgroup\$ – plannapus Feb 7 '14 at 9:18
  • 3
    \$\begingroup\$ Well, nt="99" ... your comment count seems to be wrong... :-P It is especially ironic that someone punishing regex cheaters is cheating as well :-) \$\endgroup\$ – Tomas Feb 7 '14 at 20:23
  • 1
    \$\begingroup\$ no but I'm kinda bored of spend the life here to fix this stupid script :P \$\endgroup\$ – Fez Vrasta Feb 11 '14 at 10:27

Node, 403

r('util').print("A",d.answer_count,"C",(d[m].length+d.answers.reduce(function(p,c){return p+(c[m]?c[m].length:0)},0)))})})

Only hits the API once... can likely be shortened, but I'm new to Node.

| improve this answer | |

153 151 147, C# & CsQuery

C# With CsQuery:

    var d = CsQuery.CQ.CreateFromUrl("http://qr.net/1_");
    Console.Write("A" + d[".answer"].Count() + "C" + d[".comment"].Count());

Full program:

class P{static void Main(){var d =CsQuery.CQ.CreateFromUrl("http://qr.net/1_");Console.Write("A"+d[".answer"].Count()+"C"+d[".comment"].Count());}}

118 C# & CsQuery in LINQPad or in Roslyn

If running through LINQPad is allowed then:

var d =CsQuery.CQ.CreateFromUrl("http://qr.net/1_");Console.Write("A"+d[".answer"].Count()+"C"+d[".comment"].Count());



Some more fun.

F# with CsQuery, 143:

let main x= 
 let d=CsQuery.CQ.CreateFromUrl("http://qr.net/1_")
 printfn "A%dC%d" d.[".answer"].Length d.[".comment"].Length
| improve this answer | |


Javascript + jQuery - 155

Just paste it in your console. Assumes that there would be only one page:

(function(){var n=$(".comment").length;$(".comments-link b").each(function(g,f){n+=parseInt($(f).html())});return"A"+$("#answers .answer").length+"C"+n})()
| improve this answer | |
  • 1
    \$\begingroup\$ I think that "Your script must run with this page closed when it starts." was meant to disqualify this kind of answer. \$\endgroup\$ – Peter Taylor Feb 7 '14 at 10:26
  • \$\begingroup\$ exactly, this answer is not valid \$\endgroup\$ – Fez Vrasta Feb 7 '14 at 10:26
  • \$\begingroup\$ Could be optimized a lot, but since it is invalid and unsalvageable anyway, I did not make efforts to improve it. \$\endgroup\$ – Victor Stafusa Feb 7 '14 at 21:59
  • \$\begingroup\$ You could just expand the collapsed comments calling the click event on each "show x more" \$\endgroup\$ – Fez Vrasta Feb 8 '14 at 21:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.