Lord of the Golfs

9

2

Intro

In J. R. R. Tolkien's Lord of the Rings, this phrase is on the cover of each book.

Three Rings for the Elven-kings under the sky,
Seven for the Dwarf-lords in their halls of stone, 
Nine for Mortal Men doomed to die,
One for the Dark Lord on his dark throne
In the Land of Mordor where the Shadows lie.
One Ring to rule them all, One Ring to find them,
One Ring to bring them all, and in the darkness bind them,
In the Land of Mordor where the Shadows lie

However, this isn't that interesting. It's just . Let's change this to .

What you have to do

Use the Stack Exchange API (or codegolf.stackexchange.com/users, or the Stack Exchange Data Explorer) and find the two users with the highest scores in , the newest user, and highest-reputation user with only negatively scored post.

Then, you must insert these usernames into the following text:

Three Golfs for the <highest-scored code-golf user>-king under the sky,
Seven for the <second-highest-scored code-golf user>-lord in their halls of stone,
Nine for the Mortal <newest user> doomed to die,
One for the Dark Lord <highest reuptation user with only negative scored code-golf posts>
In the land of Golfdor, where the Golfers lie
One Golf to rule them all, One Golf to find them,
One Golf to bring them all, and in the darkness bind them,
In the Land of Golfdor, where the Golfers lie

You must insert the four usernames you found into the text in the angle-brackets.

Other Rules

  • This is so the shortest code wins.
  • No URL Shorteners (including ppcg.(ga|lol))

NoOneIsHere

Posted 2016-09-16T17:02:23.353

Reputation: 1 916

1Do you want In the Land of Golfdor, where the Golfers lie in the output twice like it is on the books? – Riley – 2016-09-16T17:29:35.330

Can we assume that there will be at least one user with only negatively scored code golf posts? – Martin Ender – 2016-09-16T17:49:57.007

@Riley I don't know what you mean. I want the text outputted the way I specify it in the question. – NoOneIsHere – 2016-09-16T17:56:59.050

@MartinEnder I assume there is at least one, so you can also. If there isn't you can error. – NoOneIsHere – 2016-09-16T17:57:10.627

@NoOneIsHere I just meant that the Lord of the rings text is 8 lines long and the output text is only 7. I just wanted to make sure it wasn't a typo. – Riley – 2016-09-16T17:58:34.663

1@Riley Oh, I see. Editing. – NoOneIsHere – 2016-09-16T18:01:53.933

1Could the dark lord have 0 points in code-golf, or must it be a negative score? – MegaTom – 2016-09-16T18:50:57.157

1@MegaTom It must be negative. – NoOneIsHere – 2016-09-16T18:54:13.480

So I need to find someone who has the highest score out of all the people who have at least one code-golf post, but all of their code-golf posts are negative scoring? is that the correct interpretation? – MegaTom – 2016-09-16T19:03:19.823

@MegaTom Highest reputation, but only negative scored [tag:code-golf] posts. – NoOneIsHere – 2016-09-16T19:20:53.467

Is this query the correct way to go about it? https://data.stackexchange.com/codegolf/query/540563/find-dark-lord (I have no clue how to make this a API call)

– MegaTom – 2016-09-16T20:08:41.817

@MegaTom Yes. That is correct. – NoOneIsHere – 2016-09-16T22:10:46.787

Let us continue this discussion in chat.

– NoOneIsHere – 2016-09-16T22:24:15.217

I suggest adding gfa1.tk too, even though it was made by a URL shortener. – Erik the Outgolfer – 2016-09-16T22:53:29.197

Answers

2

PHP, 577 bytes

not tested; I currently have no system available with allow_url_fopen=On
and I didn´t take the time to copy&paste the page sources.

function g($s){return join(file("http://codegolf.stackexchange.com/$s"));}$m=preg_match_all;$m("#r-de.+/(\d+)/.+>(.+)<#U",$a=g($u="$u&filter=all"),$b);$h=$b[2];$m("#>(.+)</a.+\s1 i#",g("users?tab=NewUsers&sort=creationdate"),$c);while($a){foreach($b[1]as$i=>$n)if($m("#st \"><strong>(-?)\d+#",$e=g("search?tab=votes&q=user:$n+[code-golf]"),$d)&&$d[1][0])break 2;if($a=strstr($a,"l=\"n"))$m("#r-de.+/(\d+)/.+>(.+)<#U",$a=g("$u&page=".$p+=!$p++),$b);}$m("#<code>(.+)</code>#U",g("q/93545"),$t);echo join([1=>$h[0],3=>$h[1],5=>$c[1][0],7=>$b[2][$i];]+split("#&[lg]t;#",$t[1][2]));

breakdown

// function to get page content from ppcg
function g($s){return join(file("http://codegolf.stackexchange.com/$s"));}

$m=preg_match_all;

// A,B: highest scores: find user names
$m("#r-de.+/(\d+)/.+>(.+)<#U",$a=g($u="users?filter=all"),$b);
$h=$b[2];   // remember the names

// C: new users: find username after "1 in one day"
$m("#>(.+)</a.+\s1 i#",g("$u&tab=NewUsers&sort=creationdate"),$c);

// D: loop through users from first query
while($a)
{
    foreach($b[1]as$i=>$n)
        // find "vote-count-post" in code-golf votes for that user
        if($m("#st \"><strong>(-?)\d+#",$e=g("search?tab=votes&q=user:$n+[code-golf]"),$d)
        &&$d[1][0])             // test if highest vote is negative
            break 2;
    // none found yet?
    if($a=strstr($a,"l=\"n"))   // if there is a "next" link, get next page
        $m("#r-de.+/(\d+)/.+>(.+)<#U",$a=g("$u&page=".$p+=!$p++),$b);
}

$m("#<code>(.+)</code>#U",g("q/93545"),$t); // get code blocks from question page

echo join([         // 4. join and print
    1=>$h[0],           // first two results from first preg_match
    3=>$h[1],
    5=>$c[1][0],        // first result from second preg_match
    7=>$b[2][$i];       // $i-th username from (latest) reputation list
]+                  // 3. and replace indexes 1,3,5,7 with above array
split("#&[lg]t;#",  // 2. split by "<" and ">"
    $t[1][2]        // 1. output template is the 3rd code block
));

Titus

Posted 2016-09-16T17:02:23.353

Reputation: 13 814