11
\$\begingroup\$

Your task is to calculate the expected chance of winning for 2 players in some game, each with their own ELO Rating. Player A has ELO Ra and player B has ELO Rb

The expected score for Player A (Ea) is: 1 / (1 + 10(Rb - Ra) / 400). There is a similar equation for Player B (Eb): 1 / (1 + 10(Ra - Rb) / 400).

If you want a more copiable version: 1 / (1 + 10^((a-b) / 400))

Ea + Eb should be equal to 1.

Therefore, the score for a player is their expected chance of winning some match, in decimal.

Your program/function should take 2 inputs, Player A's ELO, and Player B's ELO, and print/return their respective chance to win in decimal format. The output must add up to one, and you must be accurate to at least 5 decimal places (0.00000). After 5 decimal places, you may have inaccurate digits, provided the two outputs still add up to one.

Examples:

1200 2100 -> 0.005591967 0.994408033 1 1 -> 0.5 0.5 60 20 -> 0.557312 0.442688 9999 9998 -> 0.501439 0.498561 9999 1 -> 0.999999 0.000001 

In the final test case, some answers use scientific exponentiation to represent the value. This is not valid.

You can see in test case 3 here that 0.557312 is not quite accurate, because the 2 should be a 1, but this is fine because it is after five decimal places and the outputs still add up to one.

This is an example of invalid output:

9999 9998 -> 0.5014391117091516, 0.49856088829084844 

This looks like it satisfies the requirements at first glance, but the numbers add up to 1.00000000000000004 and therefore the output is not valid.

Trailing zeroes in the output is fine.

You may assume a player's ELO will always be greater than 0, and nobody will have an ELO higher than 9999.

The input and output format is flexible, but the input and output must still be in base 10.

As this is , the answer with the lowest byte count will win!

\$\endgroup\$
6
  • 1
    \$\begingroup\$ +1 for ELO rating, even though I was disappointed to find you are talking about something called Elo rating instead. \$\endgroup\$ Commented Feb 22, 2017 at 3:43
  • \$\begingroup\$ You should also add the test case [9999, 998] which most answers seem to fail for. \$\endgroup\$ Commented Feb 22, 2017 at 7:42
  • \$\begingroup\$ @Emigna added, but made it more extreme ;) \$\endgroup\$ Commented Feb 22, 2017 at 7:45
  • \$\begingroup\$ @Okx: Nice. Need to go back to the drawing board to handle that one :) \$\endgroup\$ Commented Feb 22, 2017 at 8:13
  • \$\begingroup\$ It seems all answers fail on 9999, 1 including my own, so I can't post it :-( \$\endgroup\$ Commented Feb 22, 2017 at 8:50

9 Answers 9

5
\$\begingroup\$

Jelly, 9 bytes

÷400⁵*÷S$ 

Try it online! or View all test cases.

The input is an array [Ra, Rb] and the output is an array [Ea, Eb].

Explanation

÷400⁵*÷S$ Input: array [Ra, Rb] ÷400 Divide each by 400, makes [Ra/400, Rb/400] ⁵* Raise 10 to that power, makes [10^(Ra/400), 10^(Rb/400)] $ Monadic chain operating on previous result ÷ Divide each by S The sum of the whole Makes [10^(Ra/400)/(10^(Ra/400) + 10^(Rb/400)), 10^(Rb/400)/(10^(Ra/400) + 10^(Rb/400))] = [1/(1 + 10^((Rb-Ra)/400)), 1/(1 + 10^((Ra-Rb)/400))] 
\$\endgroup\$
3
  • \$\begingroup\$ What is going on here? \$\endgroup\$ Commented Feb 22, 2017 at 7:49
  • \$\begingroup\$ @Okx That is scientific notation. I'm sure you know what it is since you just edited the challenge to require standard notation after you originally said input/output format were up to us. \$\endgroup\$ Commented Feb 22, 2017 at 8:23
  • \$\begingroup\$ Did you look at the other output? It's 1.0! \$\endgroup\$ Commented Feb 22, 2017 at 11:52
3
\$\begingroup\$

Python 3, 55 47 bytes

lambda a,b:[1/(1+10**(x/400))for x in[b-a,a-b]] 

-8 bytes thanks to @math_junkie

\$\endgroup\$
2
  • \$\begingroup\$ Why not use a for comprehension: 1/(1+10**(x/400))for x in [b-a,a-b] \$\endgroup\$ Commented Feb 21, 2017 at 20:57
  • \$\begingroup\$ @math_junkie It's called a "list comprehension" \$\endgroup\$ Commented Feb 22, 2017 at 16:21
3
\$\begingroup\$

MATL, 11 bytes

10i400/^ts/ 

Takes input as a list and outputs a list.

10 % push number literal i % push input 400 % push number literal / % divide the list (by 400) ^ % power (10^list, element wise) t % duplicate the list s % sum the second one / % divide by the sum % (implicit) convert to string and display 
\$\endgroup\$
1
\$\begingroup\$

CJam, 23 bytes

XAq~_W%\.m400df/f#:)f/p 

Some other 23 byte solutions:

q~_W%\.m400df{/A\#)W#}p Aq~_W%\.m400df/f{#)W#}p 

Try it online!

Explanation

X Push 1 A Push 10 q~ Push an eval the input, a list containing 2 numbers _W% Duplicate the list and reverse it \ Swap top stack elements, so the order of answers matches the input .m Vectorized subtraction: computes Ra - Rb and Rb - Ra 400d Push 400.0 (must be a double, otherwise / performs integer division) f/ Divide both values by 400 f# Raise 10 to the power of both numbers :) Increment both numbers f/ Divide 1 by both numbers p Output the list nicely 
\$\endgroup\$
3
  • \$\begingroup\$ Fails on 9999, 1 :( \$\endgroup\$ Commented Feb 22, 2017 at 8:49
  • \$\begingroup\$ @Metoniem That's odd... it definitely has something to do with rounding issues, or maybe something like how 0.1 + 0.2 = 0.30000000000000004. I'll look into it \$\endgroup\$ Commented Feb 22, 2017 at 14:18
  • \$\begingroup\$ it actually looks fine now, ALL answers including Google's calculator return the same result as your code. I'm quite sure the test case is invalid :( \$\endgroup\$ Commented Feb 23, 2017 at 10:34
1
\$\begingroup\$

C, 63 bytes

#define M(a,b)1/(1+pow(10,(a-b)/400.)),1/(1+pow(10,(b-a)/400.)) 

Defines a (rather naive) parameterized macro M, the shortest working approach I could think of but probably still not the shortest. As such, any golfing suggestions are greatly appreciated.

Anyways, this returns 2 floating point values, E_b and E_a, respectively.

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ Fails on 9999, 1 \$\endgroup\$ Commented Feb 22, 2017 at 8:48
  • \$\begingroup\$ @Metoniem Yup. Most likely has to do with how C rounds floats. :/ I'm looking into it. \$\endgroup\$ Commented Feb 22, 2017 at 19:32
  • \$\begingroup\$ It actually seems to be correct, the test case might be invalid :( \$\endgroup\$ Commented Feb 23, 2017 at 10:33
  • \$\begingroup\$ Suggest exp10(x) instead of pow(10,x) \$\endgroup\$ Commented Jun 27, 2020 at 6:00
1
\$\begingroup\$

JavaScript (ES7), 41 35 bytes

Saved 6 bytes thanks to @Neil

a=>b=>[b=1/(1+10**((b-a)/400)),1-b] 
\$\endgroup\$
2
  • \$\begingroup\$ Since Ea + Eb = 1, just write a=>b=>[b=1/(1+10**((b-a)/400)),1-b]. \$\endgroup\$ Commented Feb 22, 2017 at 8:37
  • \$\begingroup\$ @Neil Really? I'm so shortsighted :P Thanks! \$\endgroup\$ Commented Feb 22, 2017 at 12:35
0
\$\begingroup\$

SAS Macro Language, 70 bytes

%macro e(a,b);data t;p=1/(1+10**((&b-&a)/400));q=1-p;proc print%mend; 

Output is a SAS data set where variables p and q are the players' chance of winning. 11 bytes can be saved by removing the print procedure.

\$\endgroup\$
0
\$\begingroup\$

C#, 92 bytes

Not the shortest, but it's C#, never the shortest..

Golfed

 static double[]f(int a,double b){b=1/(1+System.Math.Pow(10,(a-b)/400d));return new[]{1-b,b}; 

Ungolfed

static double[] f(int a, double b) { b = 1/(1 + System.Math.Pow(10, (a - b)/400d)); return new[] {1 - b, b}; } 
\$\endgroup\$
0
\$\begingroup\$

q, 26 bytes

{1%1+10 xexp(y-x;x-y)%400} 

Example

q){1%1+10 xexp(y-x;x-y)%400}[1200;2100] 0.0055919673088347735 0.99440803269116518 
\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.