Quick Golf: The Gold Leader

18

Challenge

Using data from the API here, output the names of the three countries with the most Olympic gold medals at the 2016 Rio Olympic Games (i.e. the first element of the returned list).

For example, at the time of posting (18:23 UTC+1, Monday, 15th August), the USA, the UK and China have the most gold medals, so the output would be:

United States
Great Britain
China

The country names must be separated by newlines and you may have a leading or trailing newlines.

Once the Olympics have finished, the program does not have to work as expected.

URL shorteners are disallowed but JSON parsing libraries are allowed.

This is code golf, so the shortest code in bytes wins.

I'm going to keep trying to get an Olympics themed challenge in here

Leaderboard

var QUESTION_ID=89919,OVERRIDE_USER=30525;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

Beta Decay

Posted 2016-08-15T17:34:41.393

Reputation: 21 478

6Would you say this is a... mini-golf? – Deusovi – 2016-08-15T19:30:32.017

1@Deusovi Ba-dum crash – Beta Decay – 2016-08-15T19:31:06.237

2I really want somebody to post a Java solution so that I can see if my C solution beats it… – Dave – 2016-08-15T19:41:48.703

@Dave You've got a Java solution now :D – Beta Decay – 2016-08-15T21:43:38.827

@βετѧΛєҫαγ dang! beats mine by 45 bytes. Thought I had a chance there… – Dave – 2016-08-15T21:55:32.270

3"The UK ... so output ... Great Britain" – trichoplax – 2016-08-15T21:57:31.370

@trichoplax In fairness team GB should probably be called team UK, but even then there's a bunch of others included too. I guess "Team UK+BOT+CD-CI-BVI-B" was judged to be too confusing (yes I just looked that up on Wikipedia). – Dave – 2016-08-15T22:25:37.403

@Dave Challenge accepted

– NonlinearFruit – 2016-08-16T05:38:47.657

Does the output have to be exactly as shown there, or can it be akin to "United States", Great Britain", "China" (with newlines, but with the quotation marks / comma) – Dylan Meeus – 2016-08-17T11:56:15.610

@DylanMeeus It has to be exactly as shown – Beta Decay – 2016-08-17T11:59:49.877

@βετѧΛєҫαγ Cheers :-) – Dylan Meeus – 2016-08-17T12:00:09.037

1@Dave NI Athletes can choose to either represent Team GB or Team Ireland. If NI Athletes were required to join Team GB, then it would be Team UK. – SGR – 2016-08-17T12:16:50.227

Answers

12

bash + w3m + grep + cut, 65 59 58 54 bytes

w3m medalbot.com/api/v1/medals|grep -m3 m|cut -d\" -f4
  • 6 bytes less thanks to @Joe's suggestions.
  • 1 byte less thanks to @YOU.
  • 4 bytes less thanks to @manatwork's suggestion that the medalbot API seems to work without www. subdomain too.

Master_ex

Posted 2016-08-15T17:34:41.393

Reputation: 526

2Change cut -d '"' to cut -d\" to save two bytes. If you use w3m instead of curl -s you can save 4 more. – Joe – 2016-08-15T19:16:49.390

you can change _n to m – YOU – 2016-08-16T11:14:53.597

@YOU: Not really because that way it'll return more lines than expected, i.e. "id": "germany", id": "colombia" etc. – Master_ex – 2016-08-16T11:17:23.067

if they cant be 1 to 3rd it will be fine, you have -m3 guard. – YOU – 2016-08-16T11:19:09.870

1@YOU: I guess this is true for the current score and it seems that it will be OK for the 2016 Olympics (except if they change United States to United States of America :P). I'll change it. – Master_ex – 2016-08-16T11:32:06.777

13

C (+sockets), 433 429 280 276 270 259 bytes

#define H"medalbot.com"
char**p,B[999],*b=B;main(f){connect(f=socket(2,1,getaddrinfo("www."H,"80",0,&p)),p[4],16);send(f,"GET http://"H"/api/v1/medals HTTP/1.1\r\nHost:"H"\r\n\r\n",69);read(f,b,998);for(f=3;f--;puts(p))b=strchr(p=strstr(++b,"_n")+9,34),*b=0;}

So it turns out that C isn't great at downloading resources from the internet and parsing them as JSON. Who knew?

This code is (naturally) super lax with error checking, so I guess if medalbot.com wanted to send malicious data they'd be able to trigger buffer overflows, etc. Also the latest code expects certain values for the constants (e.g. AF_INET = 2) which will probably be the case everywhere, but it's not guaranteed.

Here's the original code which isn't so fragile (but still isn't very robust or safe):

#include<netdb.h>
#define H"medalbot.com"
char*b,*B,d[999];struct addrinfo*p,h;main(f){h.ai_socktype=SOCK_STREAM;getaddrinfo("www."H,"80",&h,&p);f=socket(p->ai_family,p->ai_socktype,p->ai_protocol);connect(f,p->ai_addr,p->ai_addrlen);send(f,"GET http://"H"/api/v1/medals HTTP/1.1\r\nHost: "H":80\r\nConnection: close\r\n\r\n",92,0);recv(f,d,998,0);for(f=0,b=d;f<3;++f)B=strstr(b,"_n")+9,b=strchr(B,'}'),*strchr(B,'"')=0,puts(B);}

Breakdown:

                            // No imports needed whatsoever!
#define H"medalbot.com"     // Re-use the host in multiple places
char**p,                    // This is actually a "struct addrinfo*"
    B[999],                 // The download buffer (global to init with 0)
    *b=B;                   // A mutable pointer to the buffer

main(f){
    // Hope for the best: try the first suggested address with no fallback:
    // (medalbot.com runs on Heroku which has dynamic IPs, so we must look up the
    // IP each time using getaddrinfo)
    f=socket(2,1,getaddrinfo("www."H,"80",0,&p));
                            // 2 = AF_INET
                            // 1 = SOCK_STREAM
                            //     (may not match getaddrinfo, but works anyway)
                            // 0 = IP protocol (getaddrinfo returns 0 on success)
    connect(f,p[4],16);     // struct addrinfo contains a "struct sockaddr" pointer
                            // which is aligned at 32 bytes (4*8)

    // Send the HTTP request (not quite standard, but works. 69 bytes long)
    send(f,"GET http://"H"/api/v1/medals HTTP/1.1\r\nHost:"H"\r\n\r\n",69);
    // (omit flags arg in send and hope 0 will be assumed)

    read(f,b,998);          // Get first 998 bytes of response; same as recv(...,0)

    // Loop through the top 3 & print country names:
    // (p is re-used as a char* now)
    for(f=3;f--;puts(p))        // Loop and print:
        p=strstr(++b,"_n")+9,   //  Find "country_name": "
        b=strchr(p,34),         //  Jump to closing "
        *b=0;                   //  Set the closing " to \0
}

This isn't very nice for the server since we don't send Connection: close\r\n as part of the HTTP request. It also omits the Accept header since medalbot.com doesn't seem to be using compression in any case, and misses the space after Host: (again, the server seems to be OK with this). It doesn't seem as though anything else can be removed though.


Once the olympics end, the most likely behaviour for this program is to segfault trying to read memory location 9. Unless an evil hacker takes over the domain, in which case the most likely behaviour is for it to set some byte to 0 in the address info structs, which probably isn't too dangerous actually. But who can tell with these evil hackers?

Dave

Posted 2016-08-15T17:34:41.393

Reputation: 7 519

1Yeah, it's a pest with those hackers. Good thing we're on a website on which hackers of any kind are unlikely to ever turn up... – ceased to turn counterclockwis – 2016-08-16T18:26:32.133

1That was quite the leap! – NonlinearFruit – 2016-08-16T20:23:27.260

2@NonlinearFruit yeah it's amazing how many characters can be saved when you throw caution to the wind and use implementation-defined numbers directly in the code! This has become an exercise into "what is the craziest, most dangerous, most likely to break — but currently functional — way to download text in C?" – Dave – 2016-08-16T20:27:39.240

Let's just hope that little Bobby Tables doesn't have any relatives competing this year.

– GuitarPicker – 2016-08-17T11:54:02.493

Readability is also one of the first casualties of cod golf. . . – NonlinearFruit – 2016-08-17T21:46:32.500

12

PowerShell v4+, 88 69 bytes

(ConvertFrom-Json(iwr medalbot.com/api/v1/medals))[0..2].country_name

Uses iwr (the alias for Invoke-WebRequest) to grab the API. We feed that as the input parameter to the ConvertFrom-Json built-in that pulls the JSON text into a custom object array. We encapsulate that object array in parens, take the first three elements [0..2], and take the .country_name of each thereof.

Requires at least v4+ for the multiple-object-properties, else we'd need to use something like |Select "country_name" instead. Requires at least v3+ for the ConvertFrom-Json built-in.

PS C:\Tools\Scripts\golfing> .\olympics-gold-leader.ps1
United States
Great Britain
China

AdmBorkBork

Posted 2016-08-15T17:34:41.393

Reputation: 41 581

You can drop http://www. and PS doesn't mind about http:// or the site about www.. My PS (5.1.14393) also doesn't even seem to care about the .content. – Nick T – 2016-08-16T05:45:33.483

@NickT Thanks for the golfs. I didn't realize that ConvertFrom-Json didn't explicitly need only the .content portion of the web request, but it works on my setup as well. – AdmBorkBork – 2016-08-16T12:24:34.087

6

R, 98, 112, 108 bytes

golfed 4 thanks to @miff

a=jsonlite::fromJSON(readLines("http://www.medalbot.com/api/v1/medals"))
cat(a$c[order(-a$g)[1:3]],sep="\n")

First line imports data using a JSON library. Second line grabs the relevant country names. It sorts the countries by gold medals in increasing order, reverses the indices, and takes the first 3, printing them.

user5957401

Posted 2016-08-15T17:34:41.393

Reputation: 699

1I think that you can replace rev(order(a$g)) with order(-a$g) to save 4 bytes – Miff – 2016-08-17T10:22:45.770

5

JavaScript (ES6), 122 Bytes

fetch`http://www.medalbot.com/api/v1/medals`.then(a=>a.json()).then(b=>alert(b.slice(0,3).map(c=>c.country_name).join`\n`))

Due to a browser safety issue, this code must be run on medalbot.com. It does not however take advantage of that and could potentially be run elsewhere. Also note that I inserted the \n character, but am only counting is as one, because I could replace it with one

Node.js (ES6), 173 Bytes

require("http").get("http://www.medalbot.com/api/v1/medals",s=>s.on("data",d=>t+=d,t="").on("end",q=>console.log(JSON.parse(t).slice(0,3).map(a=>a.country_name).join`\n`)))

This would have been so much shorter if the API returned the data all in one stretch, but since it returns in two sections, I must concatenate the parts and combine them, and then parse them.

Node.js (ES6) + Request, 138 Bytes

require("request")("http://www.medalbot.com/api/v1/medals",(e,r,b)=>console.log(JSON.parse(b).slice(0,3).map(a=>a.country_name).join`\n`))

Better, but still not as good as the browser version. Thanks fetch API! Request is a popular HTTP client library used to simplify requests, and you can see that take effect here.

MayorMonty

Posted 2016-08-15T17:34:41.393

Reputation: 778

Which of these works in any browser? Can you put the shortest of those at the top of your answer (for the leaderboard) – Beta Decay – 2016-08-15T18:37:58.640

The top one of these works in most modern browsers, and is also the shortest. The other two are in Node.js a way of writing JavaScript on the server (plus other things).

– MayorMonty – 2016-08-15T18:40:05.020

@βετѧΛєҫαγ Take note that it doesn't work in any version of IE or Safari – MayorMonty – 2016-08-15T18:41:16.823

I see, I was getting hung up on the CORS problem – Beta Decay – 2016-08-15T18:41:56.457

4

bash + w3m + jq, 83 59 bytes

w3m medalbot.com/api/v1/medals|jq -r '.[:3][].country_name'

Thanks to Jordan for three bytes.

Thanks to YOU for 24 more bytes! Turns out the data is sorted. Wow. :D

Lynn

Posted 2016-08-15T17:34:41.393

Reputation: 55 648

1You can omit .| and index the result of sort_by directly, and you can save another byte by using [:3][] instead of [0,1,2]. All together: sort_by(-.gold_count)[:3][].country_name. – Jordan – 2016-08-15T18:58:58.687

w3m medalbot.com/api/v1/medals|jq -r '.[:3][].country_name' – YOU – 2016-08-16T13:21:39.590

4

Java 8, 261 258 bytes

This uses a lambda to save a couple bytes and the net library to get the webpage. Other than that is just Java.

()->{try{for(int i=0;i<3;System.out.println(new java.util.Scanner(new java.net.URL("http://www.medalbot.com/api/v1/medals").openConnection().getInputStream()).useDelimiter("\\A").next().split("\n")[i++*9+3].replaceAll(".* \"|\",","")));}catch(Exception e){}}

Here is my (old) POJO for testing (and golfing):

class QuickGolf {
  static void f(h x){x.g();}
  static interface h{ void g(); }
  static void main(String[] args){
    f(
      ()->{try{for(int i=0;i<3;i++){System.out.println(new java.util.Scanner(new java.net.URL("http://www.medalbot.com/api/v1/medals").openConnection().getInputStream()).useDelimiter("\\A").next().split("\n")[i*9+3].substring(21).replace("\",",""));}}catch(Exception e){}}
    );
  }
}

Update

  • -3 [16-08-17] Move print statement into for loop
  • -5 [16-08-16] Improved regex replace
  • -9 [16-08-16] Removed java.net import

NonlinearFruit

Posted 2016-08-15T17:34:41.393

Reputation: 5 334

Eep. I need to save some bytes… – Dave – 2016-08-16T06:48:48.860

I'm catching up! Now just 15 bytes behind! – Dave – 2016-08-16T20:08:02.600

Well, I was ahead for a few hours at least. It works against me, but you can probably save some more bytes by having the loop count down from 3 instead of up. – Dave – 2016-08-17T22:06:28.767

@Dave I tried having the boolean break condition just bei but Java doesn't convert boolean to int or visa versa, if that was what you were thinking. Also you had me pretty nervous with that last edit. – NonlinearFruit – 2016-08-18T02:32:32.567

3

JavaScript + jQuery, 114 100 bytes

$.get("www.medalbot.com/api/v1/medals",a=>alert(a[0][c='country_name']+'\n'+a[1][c]+'\n'+a[2][c]))

For the reason of Cross Origin Requests, this must be run from the medalbot.com domain (with jQuery).

History

  • -14 bytes thanks to @YetiCGN
  • -2 bytes thanks to Yay295

NoOneIsHere

Posted 2016-08-15T17:34:41.393

Reputation: 1 916

Or run chrome without web security { chrome.exe --disable-web-security } – 2b77bee6-5445-4c77-b1eb-4df3e5 – 2016-08-15T18:41:51.467

1save 2 bytes $.get("www.medalbot.com/api/v1/medals",a=>alert(a[0][c='country_name']+'\n'+a[1][c]+'\n'+a[2][c])) – Yay295 – 2016-08-16T18:20:52.510

3

Python 3, 202, 164 bytes.

Python 3 does not do short url/json handling. :/
Didn't realize the API already sorts by gold count

from urllib.request import*
import json
print('\n'.join(x['country_name']for x in json.loads(urlopen('http://www.medalbot.com/api/v1/medals').read().decode())[:3]))

Morgan Thrapp

Posted 2016-08-15T17:34:41.393

Reputation: 3 574

3

MATL, 67 bytes

'http://www.medalbot.com/api/v1/medals'Xi'(?<="c.+e": ")[^"]+'XX3:)

This doesn't work online because function Xi (urlread) is disallowed.

Example run:

>> matl
 > 'http://www.medalbot.com/api/v1/medals'Xi'(?<="c.+e": ")[^"]+'XX3:)
 > 
United States
Great Britain
China

Explanation

This reads the contents as a string and then applies the regex '(?<="c.+e": ")[^"]+' to extract country names. The regex uses look-behind with "c.+e" instead of "country_name" to reduce code length.

'http://www.medalbot.com/api/v1/medals'   % Push string representing the URL
Xi                                        % Read URL contents as a string
'(?<="c.+e": ")[^"]+'                     % String for regex matching
XX                                        % Apply regex
3:)                                       % Get first 3 results

Luis Mendo

Posted 2016-08-15T17:34:41.393

Reputation: 87 464

3

Python 2, 120 113 bytes

from urllib import*
for x in list(urlopen("http://www.medalbot.com/api/v1/medals"))[3:26:9]:
    print x[21:-4]

Thanks @Nick T and @Value Ink

Joe

Posted 2016-08-15T17:34:41.393

Reputation: 281

1from urllib import* and using just urlopen later saves 1 byte. Also, you should be able to take the print statement and put it right after the colon, saving you from the indentation. – Value Ink – 2016-08-15T20:10:13.580

1If you feed the urlopen object to list(), does that do the same thing as .readlines()? – Nick T – 2016-08-16T17:06:34.433

2

PHP, 205 139 124 116 111 109 bytes

I just wanted to use the new spaceship operator for PHP 7 once (EDIT: It's superfluous, as sorting isn't required):

<?$d=json_decode(file_get_contents('http://www.medalbot.com/api/v1/medals'),1);usort($d,function($a,$b){$g='gold_count';return$b[$g]<=>$a[$g];});$c='country_name';foreach([0,1,2]as$i){echo$d[$i][$c]."\n";}

If we omit the unneccesary sorting step and assume the API delivers the data already sorted by gold_count descending (as it would seem), we can shorten this further:

while($i<3)echo json_decode(file_get_contents('http://medalbot.com/api/v1/medals'))[+$i++]->country_name."
";

Note: The line break within the string is intentional to save a byte from \n

History

  • Ommitted some quotes and braces that will throw notice's, removed the $c variable for country_name index. Thanks to @manatwork for these tipps to save even more characters.
  • Thanks to @jeroen for pointing out the shorter while loop, also switched to object access to go from 124 to 116
  • Saved 5 more bytes by calling the API within the loop. Granted, it takes longer and clobbers the API, but it's Code Golf. Needs PHP 5.5 to work because of array dereferencing.
  • Saved 2 more bytes by removing the short open tag, as per this meta answer

YetiCGN

Posted 2016-08-15T17:34:41.393

Reputation: 941

Thanks! I just saw all the other entries sorting and thought I missed something. – YetiCGN – 2016-08-15T18:24:05.607

1Why are you putting "country_name" in a variable? And anyway, as error_reporting's default value not displays notices, you can omit the double quotes. And the medalbot API seems to work without www. subdomain too. Then you not need the braces around echo. – manatwork – 2016-08-16T07:24:34.520

Thanks a bunch! Well, it was late ... The $c variable is a leftover from a previous optimization that I threw away when I switched to the for loop. I guess clean coding (notice-free) is too deeply ingrained still so I don't even consider these optimizations you pointed out. So, thanks again! – YetiCGN – 2016-08-16T07:37:52.847

replacing the foreach with the following forloop: for(;$i<3;)echo$d[+$i++][country_name]." " reduces it with 5 bytes. Last space being an enter offcourse. Or just as a while loop while($i<3) – Jeroen – 2016-08-16T11:45:37.093

2

Ruby, 97 79 + -rnet/http (11) = 90 bytes

Uses a modification of the regex pattern from Luis Mendo's MATL answer, further optimized by @Jordan, since Ruby doesn't support quantifiers in lookbehinds.

-18 bytes from @Jordan.

puts Net::HTTP.get("www.medalbot.com","/api/v1/medals").scan(/"c.+"(.+)"/)[0,3]

Value Ink

Posted 2016-08-15T17:34:41.393

Reputation: 10 608

You can omit .map(&:last) entirely for 12 bytes, and omit the leading / in /api for one more. – Jordan – 2016-08-15T19:38:11.100

Also, a shorter regex that seems to work fine: /"cou.+"(.+)"/ – Jordan – 2016-08-15T19:41:53.787

Or: /y_.+"(.+)"/. – Jordan – 2016-08-15T19:47:04.477

@Jordan omitting the leading / causes errors on my Ruby version. Or it might be the network I'm on? Whatever. I went with a slightly different regex than the one you suggested but same length. – Value Ink – 2016-08-15T19:51:26.597

Interesting. FWIW I'm using 2.3.1. – Jordan – 2016-08-15T19:52:03.793

2

Mathematica 96 66 bytes

@alephalpha found a way to work directly from the file (without saving it), thereby saving 30 bytes!

Import["http://www.medalbot.com/api/v1/medals","RawJSON"][[;;3,2]]

Import imports the file as a Raw JSON file. [[;;3,2]]takes rows 1-3, second entry (country name).

DavidC

Posted 2016-08-15T17:34:41.393

Reputation: 24 524

Import["http://www.medalbot.com/api/v1/medals","RawJSON"][[;;3,2]] – alephalpha – 2016-08-16T11:46:50.360

2

PowerShell, 60

(iwr medalbot.com/api/v1/medals|convertfrom-json)[0..2]|% c*

Same basic idea as TimmyD (didn't see their answer before I posted), but quite a bit shorter :-)

Joey

Posted 2016-08-15T17:34:41.393

Reputation: 12 260

1How the devil does that |% c* parsing work? I mean, it does, I just tried it, but that's some weird syntax (it even highlights in my ISE as an error). – AdmBorkBork – 2016-08-16T20:10:23.313

1@TimmyD: ForEach-Object has a parameter set that expands a single property, or calls a method with arguments: ForEach-Object [-MemberName] <String>. The -MemberName parameter supports wildcards, so in this case it expands the only member matching that wildcard: country_name. Saves quite a few characters, too ;-) – Joey – 2016-08-16T20:14:48.273

1

BASH + w3m + core utils, 70 bytes

w3m www.medalbot.com/api/v1/medals|grep -m3 tr|cut -f6- -d\ |tr -d \",

Looks like the output comes sorted already. Just need to throw out all of the extra text.

Joe

Posted 2016-08-15T17:34:41.393

Reputation: 281

1

CJam (57 bytes)

"http://www.medalbot.com/api/v1/medals"gN/3>9%3<{'"/3=N}%

Online demo not available because it fetches content from the web. This cheats by not actually parsing JSON, but assuming that the structure won't change. (But then so do most of the existing answers, in different ways).

Peter Taylor

Posted 2016-08-15T17:34:41.393

Reputation: 41 901

1

Java 8 386 384 459 bytes

2 bytes saved from @Easterly Irk

My first code golf submission so I'm sure there's a way to save plenty of bytes, but oh well :)

It uses Gson to read the JSON

Requires:

import java.util.*;
import java.io.*;

Golfed code:

void p()throws Exception{List<A> a=new com.google.gson.Gson().fromJson(new InputStreamReader((InputStream)((new java.net.URL("http://www.medalbot.com/api/v1/medals").openConnection())).getContent()),new com.google.gson.reflect.TypeToken<List<A>>(){}.getType());a.sort((b,c)->c.gold_count.compareTo(b.gold_count));for(int i=0;i<3;)System.out.println(a.get(i++).country_name);}class A{String country_name;Integer gold_count;}

Ungolfed Code:

void p() throws Exception {
    List<A> a = new com.google.gson.Gson().fromJson(new InputStreamReader((InputStream)((new java.net.URL("http://www.medalbot.com/api/v1/medals").openConnection())).getContent()),new com.google.gson.reflect.TypeToken<List<A>>(){}.getType());
    a.sort((b, c) -> c.gold_count.compareTo(b.gold_count));
    for(int i=0; i<3;)
        System.out.println(a.get(i++).country_name);
}

class A {
    String country_name;
    Integer gold_count;
}

yitzih

Posted 2016-08-15T17:34:41.393

Reputation: 111

Can you remove the space in "g = new Gson()"? – Rɪᴋᴇʀ – 2016-08-15T21:49:01.477

2Wait, doesn't this need some imports to compile? – Dave – 2016-08-15T22:04:24.753

import statements need to be added to byte count? – yitzih – 2016-08-15T22:05:29.737

how do you calculate imports? – yitzih – 2016-08-15T22:07:17.940

Don't know what the exact rules are for Java, since I haven't posted any here before, but the usual rule is that you have to count everything which is needed to make the code valid (and from quickly looking up the Java hints page I can see various suggestions about how to minimise the import code, so I guess it must be counted). But then again, I'm also trying to get my C answer to win against Java in this question, so I'm pretty biased :D – Dave – 2016-08-15T22:16:38.953

You have to count import java.net.*;import java . . . since this requires those libraries in order to run. – NonlinearFruit – 2016-08-16T05:25:40.420

fixed it...those damn imports added in almost 80 bytes :/ – yitzih – 2016-08-16T14:11:01.963

1

Python 2, 117 bytes

from requests import *
for x in get('http://www.medalbot.com/api/v1/medals').json()[:3]:
    print(x['country_name'])

sethascope

Posted 2016-08-15T17:34:41.393

Reputation: 21

Welcome to PPCG! You can save a few bytes by removing the space between import and *, and by moving the print to directly after the colon on line 2. We generally use #s instead of ** before and after for our headers. – NoOneIsHere – 2016-08-15T22:00:36.493

1We typically require submitters to include any third-party libraries required in the answer header. Since requests isn't a standard library module, this answer's language should be "Python 2 + requests". – Mego – 2016-08-16T08:01:20.667

1

Clojure, 122 bytes

(fn[](mapv #(println(%"country_name"))(take 3(read-string(.replace(slurp"http://www.medalbot.com/api/v1/medals")":""")))))

No JSON library used :). Reads string from the URL, replaces colons with empty string and evals the string which results into Clojure map. Takes first 3 elements and maps eagerly function which prints country_name property of each elements.

cliffroot

Posted 2016-08-15T17:34:41.393

Reputation: 1 080

1

Kotlin (Script), 125 121 119 bytes

java.net.URL("http://medalbot.com/api/v1/medals").readText().lines().filter{'m' in it}.take(3).map{println(it.split('"')[3])}

Runnable with kotlinc -script <filename> or through IDEA as *.kts file.

now, if we make a VERY big assumption about the format, including numbers of lines, we can trim it to:

java.net.URL("http://medalbot.com/api/v1/medals").readText().lines().slice(setOf(3,12,21)).map{println(it.split('"')[3])}

or even

java.net.URL("http://medalbot.com/api/v1/medals").readText().lines().slice(3..21 step 9).map{println(it.split('"')[3])}

Thanks to folks at Kotlin slack team for helping me trim a couple dozens of bytes!

CypherAJ

Posted 2016-08-15T17:34:41.393

Reputation: 11

3 symbols shorter than Clojure and JS? I'll take that. – CypherAJ – 2016-08-16T21:47:01.007

1

R, 97 95 bytes

t=rjson::fromJSON(f="http://www.medalbot.com/api/v1/medals")
for(i in 1:3)cat(t[[c(i,2)]],"\n")

Little improvement over user5957401's answer, no sorting required, and shorter library name. Also my first attempt at golfing ;)

topol817

Posted 2016-08-15T17:34:41.393

Reputation: 11

You can, as in every language, omit the "www." part of the domain and save 4 more bytes if your library follows the ensuing redirect. – YetiCGN – 2016-08-18T12:54:58.053

0

Javascript 167 bytes

x=new XMLHttpRequest();x.open("GET","http://www.medalbot.com/api/v1/medals",false);x.send()
i=-3;while(i++)console.log(JSON.parse(x.responseText)[i+2]["country_name"])

Dylan Meeus

Posted 2016-08-15T17:34:41.393

Reputation: 220