21
\$\begingroup\$

This is a simple one. Given the input of a number, return the name and reputation score of the Stack Overflow user with that given ID. Your program can assume that it is always given a valid and existent user ID.

For example: given the input 764357 (which is my userID on StackOverflow) the program would return LegoStormtroopr 3,088 (approximately) it might change.

You get the URL: "https://stackoverflow.com/users/" or "http://api.stackexchange.com/2.1/users/" for free, so your score is length of your program - 31 or 39, depending on which URL you use - but declare which it is. This prevents people from abusing URL shorteners.

edit: And no calling a custom made API that query Stack Overflow, and returns just the name and score. But if you know of an offical API, then that is totally legitimate.

edit2: If you need an example input: I've given my ID below, feel free to add your own ID, username and score below to help others out. Note again, this is for the main Stack Overflow site.

764357   returns   LegoStormtroopr 3,088
\$\endgroup\$
  • \$\begingroup\$ hmm... if there are multiple users with that rep, should we pick one, or display all of them? What if there is no such user? \$\endgroup\$ – John Dvorak Oct 3 '13 at 7:47
  • 2
    \$\begingroup\$ uh... wait... of the user with that score, or of the user with that ID? \$\endgroup\$ – John Dvorak Oct 3 '13 at 7:51
  • \$\begingroup\$ @JanDvorak I've tried to clarify. The program should accept a user ID, and return the user with that ID, and that users Rep. Score. \$\endgroup\$ – user8777 Oct 3 '13 at 11:16
  • 1
    \$\begingroup\$ Should the url http://api.stackexchange.com/2.1/users/ also be "free" to avoid penalising users of the API? \$\endgroup\$ – gnibbler Oct 3 '13 at 20:10
  • 1
    \$\begingroup\$ Could we get the site=stackoverflow part for free too? \$\endgroup\$ – Johannes Kuhn Oct 4 '13 at 13:18

13 Answers 13

15
\$\begingroup\$

Shell script: 64 51 characters

curl -sL http://stackoverflow.com/users/`cat`|grep -oPm2 'n">\K[0-9,]+|e">\K[^<]+'

Sample run:

bash-4.1$ curl -sL http://stackoverflow.com/users/`cat`|grep -oPm2 'n">\K[0-9,]+|e">\K[^<]+'
662504
manatwork
834

bash-4.1$ curl -sL http://stackoverflow.com/users/`cat`|grep -oPm2 'n">\K[0-9,]+|e">\K[^<]+'
764357
Lego Stormtroopr
3,087

(Note that you have to press ^D after typing in the input interactively. Or just pipe it to the command.)

\$\endgroup\$
8
\$\begingroup\$

Ruby: 84 70 characters

s=open("http://stackoverflow.com/users/"+gets).read
puts s[/me">(.+)</,1],s[/n">([\d,]+)/,1]

Sample run:

bash-4.1$ ruby -ropen-uri -e 's=open("http://stackoverflow.com/users/"+gets).read;puts s[/me">(.+)</,1],s[/n">([\d,]+)/,1]' <<< '662504'
manatwork
834

bash-4.1$ ruby -ropen-uri -e 's=open("http://stackoverflow.com/users/"+gets).read;puts s[/me">(.+)</,1],s[/n">([\d,]+)/,1]' <<< '764357'
Lego Stormtroopr
3,087
\$\endgroup\$
  • 1
    \$\begingroup\$ You don't need full words in the regex: s[/me">(.+)</,1],s[/ation".*?([\d,]+)/,1] seems to work \$\endgroup\$ – Neil Slater Oct 3 '13 at 12:49
  • \$\begingroup\$ Correct. They were just taken from my shell script answer. (grep would display more matches for just “ation"”.) \$\endgroup\$ – manatwork Oct 3 '13 at 13:05
  • \$\begingroup\$ @Doorknob, probably you omitted the -ropen-uri option. (It's mandatory and included in the character count.) \$\endgroup\$ – manatwork Oct 4 '13 at 7:47
  • \$\begingroup\$ @manatwork Ah, didn't notice that. Okay now it works. \$\endgroup\$ – Doorknob Oct 4 '13 at 12:02
6
\$\begingroup\$

Python 2.7 - 119

(150 - 31)

Without regex:

from urllib import*
s=urlopen("http://stackoverflow.com/users/%d"%input()).read()
p=str.split 
print p(p(s,'r ')[1],' -')[0],p(p(s,'ore">')[1],'<')[0]
\$\endgroup\$
6
\$\begingroup\$

Python 3, 117

117 = 148 - 31

I don't think searching in plain HTML source code will lead to strong solution. For example, some weird stuff in one's profile may break your solutions. So I'd like to search using CSS selectors.

from lxml.html import*
C=parse('http://stackoverflow.com/users/'+input()).getroot().cssselect
print(C('[id^=u]')[0].text,C('[class$=ore]')[0].text)
\$\endgroup\$
5
\$\begingroup\$

Javascript 217

Heres a ungolfed Javascript Version using the official api with JSONP, to start with . Using the url would require XHR, which sould be quite verbose, if i find some time i'll try a more golfed version though.

d=document;function f(a){y=a.items[0];alert(y.display_name+" "+y.reputation)}x=d.createElement("script");x.src="https://api.stackexchange.com/2.1/users/"+prompt()+"?site=stackoverflow&callback=f";d.body.appendChild(x)
\$\endgroup\$
5
\$\begingroup\$

Perl 5 (with Mojolicious), 87 - 31 = 56 bytes

say/h1.*>(.*)</,$/,/core">(.*?)</ for g("http://stackoverflow.com/users/".pop)->dom

Sample run:

$ perl -Mojo -E 'say/h1.*>(.*)</,$/,/core">(.*?)</ for g("http://stackoverflow.com/users/".pop)->dom' 764357
Lego Stormtroopr
3,103

Readable & clean: 128 - 31 = 97 bytes

say $_->at("#user-displayname")->text, ": ", $_->at(".reputation a")->text for g("http://stackoverflow.com/users/".pop)->dom

Sample run:

$ perl -Mojo -E 'say $_->at("#user-displayname")->text, ": ", $_->at(".reputation a")->text for g("http://stackoverflow.com/users/$ARGV[0]")->dom' 764357
Lego Stormtroopr: 3,103
\$\endgroup\$
  • 1
    \$\begingroup\$ Is -Mojo included in the count? That costs 4 characters. \$\endgroup\$ – manatwork Oct 4 '13 at 9:20
  • \$\begingroup\$ @manatwork: No, I did not include it in the count, because the Ruby answer did not include -ropen-uri. However, I am happy to include it if your comment gets a few up votes as indication that the community wants to count these. \$\endgroup\$ – Matthias Oct 4 '13 at 9:40
  • \$\begingroup\$ Count again. It includes. pastebin.com/qZp1QgKa \$\endgroup\$ – manatwork Oct 4 '13 at 9:48
  • 2
    \$\begingroup\$ Well, I wish we have an exact documentation of the counting rule, but as I know, there is none. One thing is sure: perl's -p option is usually counted +1. Based on that I count -Mojo +4. \$\endgroup\$ – manatwork Oct 4 '13 at 10:02
  • 1
    \$\begingroup\$ Here's one set of rules we've been using a few times. \$\endgroup\$ – J B Nov 10 '13 at 18:18
4
\$\begingroup\$

R: 150-31=119

f=function(i){S=function(x)strsplit(grep(x,scan(paste0("http://stackoverflow.com/users/",i),"",sep="\n"),v=T)[1],">|<")[[1]][3];cat(S("h1"),S("=re"))}

Quite simply picks the first lines containing h1 (for the name) and =re (for the score) using grep with argument value=TRUE (here v=T) and then split the string (using strsplit at characters > and <. Inconveniently it queries the page twice (hence the two "Read n items" warnings) but that was shorter.

>f(1451109)
Read 917 items
Read 917 items
plannapus 6,566
\$\endgroup\$
4
\$\begingroup\$

Tcl, (231 - 39) 192

not the shortest way, but using the official API

package r http
package r json
set d [lindex [dict get [json::json2dict [http::data [http::geturl http://api.stackexchange.com/2.1/users/$argv?site=stackoverflow]]] items] 0]
puts [dict get $d display_name]\ [dict get $d reputation]

And in spirit of the original question:

package r http
package r json
set c [dict get [json::json2dict [http::data [http::geturl http://api.stackexchange.com/2.1/users/?order=desc&sort=reputation&site=stackoverflow&min=$argv&max=$argv]]] items]
foreach d $c {puts "[dict get $d display_name] [dict get $d reputation]"}

Finds users with that reputation

\$\endgroup\$
  • \$\begingroup\$ Sorry about that mixup! \$\endgroup\$ – user8777 Oct 3 '13 at 21:33
  • \$\begingroup\$ @LegoStormtroopr: I wrote this answer when it was clear that you mean the userid, but I liked to show that the official API is able to solve the original question too. \$\endgroup\$ – Johannes Kuhn Oct 5 '13 at 12:32
3
\$\begingroup\$

Shorter CoffeeScript: 143 characters (182 - 39)

This relies on the API always returning the object keys in the same order, but shaves off 7 characters.

f=(r)->u=Object.keys(items[0]);alert u[3]+' '+u[5]
d=document
j=d.createElement('script')
j.src="//api.stackexchange.com/2.1/users/"+prompt()+'?site=diy&jsonp=f'
d.body.appendChild j

CoffeeScript: 150 characters (189 - 39)

f=(r)->u=r.items[0];alert u.display_name+' '+u.reputation
d=document
j=d.createElement('script')
j.src="//api.stackexchange.com/2.1/users/"+prompt()+'?site=diy&jsonp=f'
d.body.appendChild j

(Note that the program prompts you for "undefined" -- it's asking for the User ID.)

\$\endgroup\$
3
\$\begingroup\$

R - 84

84 = 115 - 31

sub(".*\\/(.*)\\?.*>(.*)<.*","\\1 \\2",grep("b=r",scan(paste0("http://stackoverflow.com/users/",scan(n=1)),""),v=T)[1])

Simulation:

> sub(".*\\/(.*)\\?.*>(.*)<.*","\\1 \\2",grep("b=r",scan(paste0("http://stackoverflow.com/users/",scan(n=1)),""),v=T)[1])
1: 1201032
Read 1 item
Read 2976 items
[1] "flodel 31,093"
\$\endgroup\$
  • \$\begingroup\$ +1 This is a very impressive use of regular expressions. \$\endgroup\$ – Sven Hohenstein Nov 17 '13 at 19:06
3
\$\begingroup\$

101 100 - CoffeeScript with jQuery

$.getJSON "http://api.stackexchange.com/2.1/users/#{prompt()}?site=stackoverflow",(d)->alert [d.items[0].reputation,d.items[0].display_name]

Here's a fiddle; just know that it prompts you when you first open the page, so have a ID ready, or press Run again.

Or we can be super hacky to save a whole character!

$.getJSON "http://api.stackexchange.com/2.1/users/#{prompt()}?site=stackoverflow",(d)->`with(d.items[0])alert([reputation,display_name])`;1
\$\endgroup\$
2
\$\begingroup\$

Python 2.7 - 112

112 = 143 - 31

A newer, short version that uses some of the ideas from Steven Rumbalski answer, while still using Regex.

import urllib,re
r=re.findall('r (.*?) -|re">(.*?)<',urllib.urlopen("http://stackoverflow.com/users/%d"%input()).read())
print r[0][0],r[2][1]

133 = 164 - 31

Here is a base version for people to work from, but I'm sure people can get even shorter.

import urllib,re
u=input()
s=urllib.urlopen("http://stackoverflow.com/users/%d"%u).read()
r=re.findall('name.*?>(.*?)</h1|tion.?>(.*?)</a',s)
print r[0][0],r[1][1]
\$\endgroup\$
  • \$\begingroup\$ this doesn't seem to work. http://stackoverflow.com/users/12340 is 404. \$\endgroup\$ – John Dvorak Oct 3 '13 at 7:50
  • \$\begingroup\$ @JanDvorak, try with 499214 instead of 12340 \$\endgroup\$ – Peter Taylor Oct 3 '13 at 8:14
  • \$\begingroup\$ @PeterTaylor then the question is incorrect. \$\endgroup\$ – John Dvorak Oct 3 '13 at 8:15
  • 2
    \$\begingroup\$ @JanDvorak Obviously, the user with that ID doesn't exist. \$\endgroup\$ – user8777 Oct 3 '13 at 11:18
1
\$\begingroup\$

GNU Awk: 217 characters

Just because GNU awk supports TCP natively: no module/library/external tool.

{RS="\r"
print h("/users/"$0,$0,"/",4),h($2,$2"\\?","<|>",3)}function h(p,m,r,f){d="stackoverflow.com"
g="/inet/tcp/0/"d"/80"
print"GET "p" HTTP/1.1\nHost:"d"\n"|&g
close(g,"to")
while(g|&getline)if($0~m){close(g,"from")
split($0,a,r)
return a[f]}}

Sample run:

bash-4.1$ awk '{RS="\r";print h("/users/"$0,$0,"/",4),h($2,$2"\\?","<|>",3)}function h(p,m,r,f){d="stackoverflow.com";g="/inet/tcp/0/"d"/80";print"GET "p" HTTP/1.1\nHost:"d"\n"|&g;close(g,"to");while(g|&getline)if($0~m){close(g,"from");split($0,a,r);return a[f]}}' <<< 662504
manatwork 854

bash-4.1$ awk '{RS="\r";print h("/users/"$0,$0,"/",4),h($2,$2"\\?","<|>",3)}function h(p,m,r,f){d="stackoverflow.com";g="/inet/tcp/0/"d"/80";print"GET "p" HTTP/1.1\nHost:"d"\n"|&g;close(g,"to");while(g|&getline)if($0~m){close(g,"from");split($0,a,r);return a[f]}}' <<< 764357
lego-stormtroopr 3,947
\$\endgroup\$

Your Answer

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