Martin vs Dennis - Round 1: Who has more rep?

33

7

I know there have been a lot of challenges about "the two best code-golfers in the world", but this one is a bit more unique, being Round 1 in a series of (future) challenges involving the two of them.


Your task is to write a program or function that returns two different non-whitespace ASCII strings, corresponding to the one who has more reputation at the moment the program is ran, between Dennis ♦ and Martin Ender ♦. The tricky part is that you must output the exact string "tie" in case the reputation is identical (not likely), and the two different non-whitespace ASCII strings mentioned above should be different than "tie" *.

No input can be taken, such as usernames or user ids. As usual, URL shorteners are forbidden, and so are the common loopholes.

Examples:

Let the chosen string for Dennis be "D" and the chosen one for Martin Ender be "M" (should be specified)

If Dennis' rep > Martin Ender's rep => D
If it's the other way around => M
If it's a tie => tie 

IMPORTANT! Voting on posts by Dennis & Martin for the sole purpose of affecting a tie in order to test the solutions below constitutes targeted voting which is forbidden across the Stack Exchange network. If you want to test that a solution properly outputs tie then change the IDs in it to those of 2 users you know to be tied. See this Meta post for more details.

*I think no one would have used that, anyway

Mr. Xcoder

Posted 2017-05-10T12:47:00.273

Reputation: 39 774

33"... the two best code-golfers in the world ..." [citation-needed] – Martin Ender – 2017-05-10T12:48:13.107

9Can we assume that they will always be #1 and #2 in this community? – ovs – 2017-05-10T14:24:55.303

Yes, you can, as long as they are the #1 and #2, then you update the answer :) – Mr. Xcoder – 2017-05-10T15:09:44.580

7A friendly reminder: targeted voting is forbidden on the entire Stack Exchange network. Voting on Martin's and my posts just to test submissions to this challenge is not allowed. – Dennis – 2017-05-11T17:12:53.180

@Dennis we all know that, but thanks for the reminder. It was just a joke, don't take it seriously – Mr. Xcoder – 2017-05-11T17:14:38.703

The thing is, if you look at Martin's and my own rep history over the last couple of days, it seems like a handful of users did need a reminder. – Dennis – 2017-05-11T17:20:24.790

@Mr.Xcoder, feel free to edit/move that notice I just edited in. – Shaggy – 2017-05-12T07:41:40.360

2@Shaggy It's great that you have added that note. Hopefully, the users involved will stop doing that – Mr. Xcoder – 2017-05-12T11:24:33.827

Sorry for my grammar, I meant to say Although one of the answers has been accepted, it would be nice to see some more interesting solutions – Mr. Xcoder – 2017-05-13T11:41:48.010

What do you exactly mean by "interesting"? :) – HyperNeutrino – 2017-05-14T22:14:33.493

Any new smart answer that uses a different approach than the current ones – Mr. Xcoder – 2017-05-15T04:25:12.373

So ... when's round 2?! – Shaggy – 2017-05-31T08:54:01.217

@Shaggy it's coming soon. I have some minor things to change till I post it. – Mr. Xcoder – 2017-05-31T10:57:06.117

1To @MartinEnder at the top, citations are unneeded for facts that are common knowledge. – Gryphon – 2017-08-02T00:10:13.517

still waiting for round 2 – Okx – 2017-10-22T16:04:01.247

Answers

20

05AB1E, 65 64 bytes

Code:

•в=6{•5ôvy’ƒËŠˆ.‚‹º.ŒŒ/†š/ÿ’.w’„Ö="ˆ"’¡1èт£þ}})ZQā*O<“D M·‡“#è

Uses the 05AB1E encoding.


Explanation:

•в=6{• converts the number в=6{ from base 255 to base 10, resulting in 1201208478. The first half being the ID of Dennis (12012) and the second half being the ID of Martin (8478). Split into pieces of 5 using to get the following array:

['12012', '08478']

Luckily, we can leave the leading zero from Martin's ID, since this will still work (check the link before clicking to see the leading zero).

We now loop through this array using vy and construct the following string from this 05AB1E code:

’ƒËŠˆ.‚‹º.ŒŒ/†š/ÿ’  -->  codegolf.stackexchange.com/users/ÿ

Whereas ÿ is the current element of the iterator (using string interpolation) Try it online!

After constructing the link, .w reads all data from the link, resulting into a huge amount of text. To scrape the reputation from this, we need to split on the string title="reputation". Or in a more compressed version: ’„Ö="ˆ"’. Split on this piece of string (with ¡) and get the second element (with ) and keep the first 100 characters (with т£).

Now, our scraped text looks a bit like this:

>
        139,883 <span class="label-uppercase">reputation</span>
   </div>

<div class="ba

This part is easy, we just remove anything but digits to remain the reputation number, for which we have a builtin (þ). We end the loop and wrap everything into an array }}).

Finally, we can go on to processing the reputation numbers:

ZQā*O<“D M·‡“#è   -   On stack: an array in the format [Dennis rep, Martin rep]

Z                 # Get the maximum of the array
 Q                # Check for equality with the array
  ā*              # Multiply by it's index (1-indexed)
    O<            # Sum and decrement by 1
      “D M·‡“#    # Push the array ['D', 'M', 'tie']
              è   # Get the element on the index of the sum

Which results in either D, M or tie.

Adnan

Posted 2017-05-10T12:47:00.273

Reputation: 41 965

2I didn't know that 05AB1E can access internet APIs, this answer kind surprises me => +1 – Mr. Xcoder – 2017-05-10T18:24:10.963

I always like how you and others come up with ways to get a certain number. :) +1 Btw, is the part "second element (with 1è) and keep the first **100 characters** (with т£." supposed to be completely in code-blocks, or should it be "second element (with ) and keep the first 100 characters (with т£)." instead? I guess a typo, but if it's supposed to be like this I'm confused.. – Kevin Cruijssen – 2017-05-10T20:57:17.800

@KevinCruijssen Huh, I have no idea how that happened, but it's fixed now. Thanks for the heads up! :) – Adnan – 2017-05-10T21:00:14.370

it seems incorrect (I don't know how to correct this kind of code, sorry), Dennis: 140,033; Martin: 140,003, but I tried your code here https://tio.run/nexus/05ab1e#@/@oYdGFTbZm1UDa9PCWsspHDTOPTTrcfXTB6Ta9w02PGmY9ath5aJfe0UlHJ@k/alhwdKH@4f1ANXrlQOJRw7zD02yVDjedblMCcg8tNDy84mLTocWH99XWakYFHmnU8rd51DDHRcH30PZHDQuBTOXDK/7/BwA, it yield tie. Shouldn't it ouput D instead?

– Eddie – 2017-05-11T08:39:41.303

@Eddie .w requires web access, which is restricted on TIO (it runs 05AB1E in safe mode). In the offline interpreter, it should work. – Adnan – 2017-05-11T08:44:24.497

@Adnan Nitpick: TIO no longer runs 05AB1E is safe mode, but the sandbox that runs all user requests cuts off all internet access. – Dennis – 2017-05-11T17:16:02.980

@Dennis Oh, that's neat! Thanks for letting me know :) – Adnan – 2017-05-11T18:39:26.700

19

PowerShell v3+, 147 123 119 103 101 96 Bytes

$a,$b=irm api.stackexchange.com/users/12012`;8478?site=codegolf|% I*|% r*n;$a-$b|% T*g "D;M;Tie"

Saved 24 bytes using true/false output instead of the names.

Saved another 4 by restructuring the final checks.

saved 16 by getting only the reputations of the two users from the request, saves having to use the |% r*n more than once, also means we can get rid of like a million brackets, and two useless variables.

-2 thanks to TessellatingHeckler - using an escape char instead of two doublequotes for the url, also removed the @ from the array which was un-needed (oopsie)

used a weird .ToString trick I never knew existed until now reccomended by TessellatingHeckler -5, and finally below 100.


Version which returns names:

$a,$b=irm "api.stackexchange.com/users/12012;8478?site=codegolf"|% I*
if(($c=$a|% r*n)-eq($d=$b|% r*n)){"tie"}else{@(($a|% d*),($b|% d*))[$c-lt$d]}

this looks pretty messy due to the shortening of parameter names.

anywhere |% r*n appears we're getting the ReputatioN, and |% d* is the Display_name

uses Invoke-RestMethod (alias irm) to query the API, stores the result named Items (gotten using |% I*), into the two variables $a & $b, one for each pro golfer's, the ToString (|% T*g) trick results in one of the values D,M or Tie if the number is odd/even/zero.

colsw

Posted 2017-05-10T12:47:00.273

Reputation: 3 195

I did not expect powershell to be the shortest. +1 – Rɪᴋᴇʀ – 2017-05-10T15:30:37.327

@Riker Pyth would've presumably been, but it has a horrible bug. – Erik the Outgolfer – 2017-05-10T15:46:37.747

@EriktheOutgolfer it's not a legitimate victory but i'll take it. would be nice to see a non-competing pyth answer after the bug is fixed though. – colsw – 2017-05-10T15:51:38.297

This wont work in PowerShell 2.0 so i think you need to add a version to your post. Beautiful to look at though. – Matt – 2017-05-10T16:11:07.430

@Matt I think the irm command was first added in v3 - don't have access to a v3 shell to check sadly, definitely not in v2 though, thanks for that. – colsw – 2017-05-10T17:03:48.330

1Fine, you win; no way I'm going to beat this now! – Shaggy – 2017-05-10T17:46:33.977

Got a short domain? Put a reverse proxy rewrite on it to shorten that hostname... Tried making a hosts file entry but the SE servers need the host header.. – Caius Jard – 2017-05-10T17:52:10.707

@ConnorLSW It was that and the Foreach-Object syntax you are using. – Matt – 2017-05-10T17:57:01.120

9So your code is 103! = 9.902900716486180407546715254581773349090165822114492483005280554699... × 10^163 bytes long..? :P – totallyhuman – 2017-05-11T00:07:40.833

@totallyhuman You beat me to it ;) – Brian McCutchon – 2017-05-11T00:26:17.740

1@TessellatingHeckler check the answer for the last bit, you got it below 100! - never knew ToString worked like that with +/- numbers, will remember for future. – colsw – 2017-05-11T14:35:06.640

16

Python 2, 160 bytes

from requests import*
print cmp(*[get('http://api.stackexchange.com/users/12012;8478?%ssite=codegolf&filter=!9aK21rboZ'%s).text for s in'order=asc&',''])or'tie'

Not the shortest Python answer, but the shortest one so far that doesn't make any assumptions.

Prints 1 if Martin has more rep, -1 if I do.

Dennis

Posted 2017-05-10T12:47:00.273

Reputation: 196 637

14

JavaScript (ES6), 167 156 146 144 141 132 103 bytes

Stupid fetch and its stupid, expensive Promise chaining!

Assumes, as currently allowed, that Dennis & Martin will always be the 2 top ranked users. Needs to be run from the root level of api.stackexchange.com. Returns a Promise object (as is now permitted by consensus) containing tie or the JSON object for whoever has the most rep at the time. If the JSON object isn't considered valid output then add 5 bytes for .link.

_=>fetch`users/?site=codegolf`.then(r=>r.json()).then(({items:[j,i]})=>j[r="reputation"]==i[r]?"tie":j)
  • Saved 11 bytes thanks to Kevin suggesting I return the profile link rather than the first letter of the display_name, which also provide better future-proofing against them changing their usernames to start with the same letter!
  • 5 bytes saved adapting a tip from kamoroso94 on a another solution of mine.

Try It

f=
_=>fetch`//api.stackexchange.com/users/?site=codegolf`.then(r=>r.json()).then(({items:[j,i]})=>j[r="reputation"]==i[r]?"tie":j)
f().then(console.log)

Alternative

If a time comes that Dennis & Martin aren't at the top and we still want to know who has the most rep between them then we'd need the following, at a cost of an additional 10 bytes.

_=>fetch`users/12012;8478?site=codegolf`.then(r=>r.json()).then(({items:[j,i]})=>j[r="reputation"]==i[r]?"tie":j)

Shaggy

Posted 2017-05-10T12:47:00.273

Reputation: 24 623

2You can change .display_name[0] to .display_name, or an even shorter alternative that is still unique for both of them: .link. ;) Or just the entire JSON, but I'm not sure if it fits in the alert-popup. – Kevin Cruijssen – 2017-05-10T13:43:06.357

Thanks, @KevinCruijssen; I had to use an extract of the username as Martin's contains a space, which isn't allowed. Good shout on using link, though, I was using a filtered API query to only return the info I needed. – Shaggy – 2017-05-10T14:00:02.883

@KevinCruijssen I've dumped whole HTML pages into alert popups when dealing with AJAX returns. It can handle it. – Draco18s no longer trusts SE – 2017-05-10T15:17:16.273

@Draco18s, alerting a JSON object, though, will just display [object Object]. – Shaggy – 2017-05-10T15:36:01.900

@Shaggy True, true, it would. – Draco18s no longer trusts SE – 2017-05-10T15:41:39.953

9

Python 3, 160 157 151 bytes

from requests import*
a,b,*c=get('http://api.stackexchange.com/users?site=codegolf').json()['items']
r='reputation'
print(['tie',a['link']][a[r]>b[r]])

-3 bytes thanks to @KevinCruijssen

Prints a link to the user having more reputation

Assumes they are on #1 and #2


Without making any assumptions, Python 2, 157 bytes:

from requests import*
a,b=get('http://api.stackexchange.com/users/8478;12012?site=codegolf').json()['items']
r='reputation'
print['tie',a['link']][a[r]>b[r]]

ovs

Posted 2017-05-10T12:47:00.273

Reputation: 21 408

6

Python, 226 225 221 bytes

I feel like this is too long.

import requests as r,re
def f(i):d=re.sub('[, ]','',r.get('http://codegolf.stackexchange.com/users/'+i).text);D=d.index('"reputation">')+14;return int(d[D:d.index('<',D)])
a=f('8478')
b=f('12012')
print([a>b,'tie'][a==b])

Prints "True" if Martin has more rep than Dennis, "False" if Dennis has more rep than Martin, and "tie" if they have the same (theoretically. I can't test this :P).

https -> http for 1 byte thanks to @KevinCruijssen! re as r, r.sub -> re, re.sub for 4 bytes thanks to @ovs!

HyperNeutrino

Posted 2017-05-10T12:47:00.273

Reputation: 26 575

I'm not entirely sure, but is it possible to change https to http? I know PPCG is completely https now, but perhaps it auto-directs to HTTPS when you navigate to HTTP in Python, just as it does in a browser? – Kevin Cruijssen – 2017-05-10T13:38:57.410

@KevinCruijssen Ah yes, I don't know what I was thinking there. Thanks! – HyperNeutrino – 2017-05-10T13:41:24.860

1You don't need re as R. Just use import requests as r,re and re.sub – ovs – 2017-05-10T13:53:21.490

@ovs Heh, my original approach was different Thanks! – HyperNeutrino – 2017-05-10T14:04:11.793

I think you can use the cmp function to save some bytes by replacing the last three lines with something like print['tie',0,1][cmp(f('8478'),f('12012'))] – Loovjo – 2017-05-10T15:29:03.240

@Loovjo Thanks, but unfortunately this only works for Python 2, and the requests part seems to fail for py2. – HyperNeutrino – 2017-05-10T17:17:27.703

6

PHP, 167 Bytes

prints -1 for Dennis , 1 for Martin Ender. tie in case of a tie

<?=($b=($t=json_decode(gzdecode(join(file('http://api.stackexchange.com/users/12012;8478?site=codegolf&order=asc'))))->items)[0]->reputation<=>$t[1]->reputation)?:tie;

Jörg Hülsermann

Posted 2017-05-10T12:47:00.273

Reputation: 13 026

4

Python 2, 228 223 204 199 bytes

I did this on a mobile hotspot so... it's not great... Assumes both of them will always be in the same hundred thousand. Doesn't assume anything now. :D

import urllib as l,re
f=lambda i:int(re.search('n">\s*([\d,]+)',l.urlopen('http://codegolf.stackexchange.com/users/%d'%i).read()).group(1).replace(',',''))
d,m=f(12012),f(8478)
print[d>m,'Tie'][d==m]

Prints True if Dennis has more reputation than Martin, False otherwise and Tie if they are... tied.

totallyhuman

Posted 2017-05-10T12:47:00.273

Reputation: 15 378

4

Bash + jq, 140 133 bytes

w3m 'api.stackexchange.com/users/12012;8478?site=codegolf&sort=name'|jq '.items|map(.reputation)|1/(index(min)-index(max))'||echo tie

Formatted and explained

First, we curl w3m the API (and use --compressed, or short --com to un-gzip):

w3m 'api.stackexchange.com/users/12012;8478?site=codegolf&sort=name'

That's some JSON. Notice the order ist stable, not based on reputation. JQ then processes the JSON, which is what it's made for.

.items                          # take the items array
| map(.reputation)              # extract only the reputations
| 1 / 
  (index(min)-index(max))       # This checks if the bigger value is first (1) or last (-1) in array

We use 1/x above to generate an division-by-zero error when min==max, so in a tie situation. The ||echo tie in bash catches that.

Note that a warning is printed on stderr by JQ in that case, but we consider only stdout the actual result of the program ;)

opatut

Posted 2017-05-10T12:47:00.273

Reputation: 141

1You can use w3m instead of curl --com to save a few bytes. Also, I think it's worth mentioning that this requires jq 1.5, as jq 1.4 didn't raise an error for division by zero. – Dennis – 2017-05-12T19:27:24.033

True, thanks for the hint. W3m is exactly what I was looking for. – opatut – 2017-05-13T07:06:46.497

1

Stackexchange API Data Explorer, 184 180 bytes

Thanks to @Kevin Cruijssen for -4 bytes

DECLARE @M int,@D int;SELECT @M=reputation from users where id=8478;SELECT @D=reputation from users where id=12012;IF @D=@M PRINT('tie')ELSE BEGIN;IF @D>@M PRINT(1)ELSE PRINT(2)END

Prints 1 for Dennis and 2 for Martin

Since i only yesterday learned about the SEADE this should be very beatable.

Try it here

Roman Gräf

Posted 2017-05-10T12:47:00.273

Reputation: 2 915

You can change 'D' and 'M' to 0 and 1. – Kevin Cruijssen – 2017-09-19T09:20:48.200