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.

Expected example output:

A12C40


• Little comment to check something, if you dont mind ;) Feb 7 '14 at 7:30
• All the comments Feb 7 '14 at 7:31
• 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). Feb 7 '14 at 7:37
• How long until someone writes a program that read the most upvoted answer here, and run it ? :D Feb 7 '14 at 14:26
• Is this a clever scheme to get the most viewed question through people testing their scripts? Feb 7 '14 at 16:09

# 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

href

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

• In the interest of breaking a few more scripts that use css selectors, perhaps a <a href="" class="comment>comment link</a> might work? Feb 7 '14 at 21:10
• Denis unfortunatelly SE will not allow you to display this. You can test on your own answer :) Feb 7 '14 at 21:20
• I check for > so it's not breakable Feb 8 '14 at 20:45
• @FezVrasta ermm.. not breakable? Then how is it possible than I broke it? ;) Feb 9 '14 at 11:42
• @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 :) Feb 9 '14 at 12:15

### XQuery, 169, 160, 165

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)


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.

• Would be even shorter (by using the doc() function) if this page would be valid XML... Feb 7 '14 at 10:58
• And this seems to be the first answer ever on code-golf using XQuery... turns out to be quite suitable :) Feb 7 '14 at 11:00
• on this site I discover a new language every day, this one is quite interesting, thanks. Does it count hidden comments? Feb 7 '14 at 11:02
• @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) Feb 7 '14 at 11:05 # Python 3, 180 import lxml.html as h s=h.parse('http://qr.net/1_').find('body').cssselect 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. • blender: no luck even with block code :P Feb 7 '14 at 9:34 • @FezVrasta: I'm getting A13C20. Include an angled bracket in the regex and I think it should be good, as those are escaped. Feb 7 '14 at 9:37 • Yes I've already did it. thanks Feb 7 '14 at 9:43 • Hmmm... "Ignore this stuff" huh? What happens if someone edits that out of the answer, then? – Iszi Feb 7 '14 at 19:55 • Invalid syntax. ,sep='' 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 A16C76  ### Explanation curl Transfer a URL. • -s in curl is for silent. And -L to follow redirects. awk 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.
• so it does not count the collapsed comments? Feb 7 '14 at 12:33
• 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? Feb 7 '14 at 12:35
• @plannapus yes, error from copy paste. Solved, thanks! Feb 7 '14 at 12:36
• Just tested your code, and it reports "A14C159", which I believe is not quite correct. Feb 8 '14 at 9:23
• 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 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)));

• 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? Feb 7 '14 at 12:27
• @FelixEve, I think it's probably counting the deleted answer. (count($i)-1) corrects the count to not include the question. Feb 7 '14 at 13:02 • @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. Feb 7 '14 at 18:28 • from PHP 5.4 you can use [] instead of array() to initialize Feb 7 '14 at 19:33 • 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. ;-) ) 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:

library(XML)
b=htmlParse("https://codegolf.stackexchange.com/questions/20277")
z=xpathApply
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
y=gsub("[^0-9]","", #This is more straightforward as the number of answers is given on front page.
cat("A",y,"C",x,sep="")


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:

library(XML);h=htmlParse;z=xpathApply;v=xmlValue;a=xmlAttrs;s=sapply;c="http://codegolf.stackexchange.com";f=function(b,i){do.call(sum,s(z(b,"//tbody",a)[i],function(x)as.integer(x[[1]])))+length(z(b,"//tr[@class='comment']",v))};b=h(paste0(c,"/questions/20277"));x=f(b);u=unique(s(z(b,"//div[@class='pager-answers']/a",a),[,1));if(length(u))x=x+sum(s(u,function(x)f(h(paste0(c,x)),-1)));y=gsub("[^0-9]","",z(b,"//div[@id='answers-header']/div/h2",v)[[1]]);cat("A",y,"C",x,sep="")


Indented:

library(XML)
h=htmlParse
z=xpathApply
v=xmlValue
a=xmlAttrs
s=sapply
c="http://codegolf.stackexchange.com"
f=function(b,i){do.call(sum,s(z(b,"//tbody",a)[i],function(x)as.integer(x[[1]])))+length(z(b,"//tr[@class='comment']",v))}
b=h(paste0(c,"/questions/20277"))
x=f(b)
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
cat("A",y,"C",x,sep="")


Tried on this question and outputted: A125C499.

• +1 for using R, clear underdog but beautiful language :) Feb 7 '14 at 21:36

## HTML, 37

Sorry, Blatant rule abuse follows!

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


### Explanation

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

where the callback is:

(function(d){
c=d.items.length;
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=...

(function(d){
a=0;
g=[];
d.items.map(function(f){
a++;
});
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=...

(function(d){
c+=d.items.length;
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!

• Well, why not HTTP, 8 chars q0x.eu/1 then? PS: legitimate solutions can't beat Perl anyways ;-) (blatant challenge) Feb 7 '14 at 21:21
• @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... Feb 7 '14 at 21:23

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

require'open-uri';require'json'


That's 242 without the shortened url:

require'open-uri';require'json'


require'open-uri';require'json'
q=20277


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

• damnit, that was my idea! Feb 7 '14 at 21:48
• Actually, your use of the filtered API was better. Doing the same here shaves almost 120 characters off of my original answer. :-) Feb 7 '14 at 22:50

## Python with stackpy 160

Implementation

s=__import__("stackpy").Site("codegolf");q=s.questions(20277);a=q.answers


Output

A13C60


Note

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.

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

A13C60

• 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? Feb 8 '14 at 10:14
• 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. Feb 8 '14 at 12:07
• 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. 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:

$('.comments-link').click(); setTimeout("alert('A'+$('.answer').length+'C'+$('.comment').length)",999)  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 • This will not work if the page is closed, like the question requires. – bodo Feb 7 '14 at 21:09 • Yeah, jQuery performs poorly on closed pages :-) I guess it's out of competition then, but cannot really be missing! :) Feb 7 '14 at 21:11 • I did that and my answer was deemed invalid. I deleted it. Feb 7 '14 at 21:14 • @Victor, why not keep it just for fun? How many chars did you have? Feb 7 '14 at 21:17 • @Tomas. Ok, I undeleted it. 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">'));  Explanation: <? // 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
echo
'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":

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

## Node, 403

r=require;m='comments'


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

## 153151 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());


Produces:

A14C48

Some more fun.

### F# with CsQuery, 143:

[<EntryPoint>]
let main x=
let d=CsQuery.CQ.CreateFromUrl("http://qr.net/1_")