# American odds to probabilities

American odds (aka moneyline odds) are numbers like $$\+150\$$ or $$\-400\$$ used to express how much a winning bet would pay out. Convert odds to a fair win probability like this:

• Positive odds $$\+n\$$ with $$\n \geq 100\$$ correspond to $$p=\frac{100}{100+n},$$ producing a probability with $$\0 < p \leq 1/2\$$.
• Negative odds $$\-n\$$ with $$\n > 100\$$ correspond to $$p=\frac{n}{100+n},$$ producing a probability with $$\1/2 < p < 1\$$.

Note that in both formulas above, $$\n\$$ is the absolute value of the input. Inputs with absolute value under $$\100\$$ are invalid, and so is $$\-100\$$ (since $$\+100\$$ is used for $$\p=1/2\$$), so you don't need to handle these.

The input will be a whole number. If you take it as a string, expecting a leading + for positive values is optional.

Your output can be a decimal to some reasonable precision or a reduced fraction.

Test cases

+1500   0.0625
+256   0.2808988764044944
+100   0.5
-200   0.6666666666666666
-300   0.75

• Can the input be 0? Commented Sep 12, 2023 at 17:54
• @noodleman No, the input is always $>=100$ or $<-100$.
– xnor
Commented Sep 12, 2023 at 17:54
• Why do Americans have to use weird units for everything? Commented Sep 14, 2023 at 12:25
• @TrangOul As an American, it seemed strange to me, too. But looking deeper, I found it explained in a way that made more sense: negative moneyline odds represent the amount of money you need to wager to have a chance of winning $100; positive odds represent the amount of money you could win if you wager$100. This has the nice property that the opposite odds are inverses. 1-to-10 odds are $-1000$ , while 10-to-1 odds are $+1000$ . Commented Sep 15, 2023 at 14:58

# Python, 25 bytes

lambda x:x/(~99-abs(x))%1


Attempt This Online!

### Original Python, 26 bytes

lambda x:-x/(100+abs(x))%1


Attempt This Online!

Test bed from @MTN via @AnttiP.

### How?

Based on the observation

$$\-n \equiv 100 \mod 100+n\$$

# Jelly, 7 bytes

,³ṢAÄ÷/


Try it online!

Function I/O only because lmao ³. (Replace with ȷ2 if that's too borderline.)

                                  n ≥ 100         | n < -100
,³         Pair n with 100.       [n, 100]        | [n, 100]
Ṣ        Sort.                  [100, n]        | [n, 100]
A       Map absolute value.    [100, n]        | [-n, 100]
Ä      Cumsum.                [100, 100 + n]  | [-n, 100 - n]
÷/    Divide.                100 / (100 + n) | -n / (100 - n)


# R, 24 bytes

\(n)(-n/(100+abs(n)))%%1


Attempt This Online!

Port of loopy walt's Python answer.

# Python, 33 bytes

lambda n:1/[1+n/100,1-100/n][n<0]


Attempt This Online!

# Ruby, 29 26 bytes

->n{(n>0?100:n=-n)/n+=1e2}


Attempt This Online!

Saved 3 bytes thanks to @MTN and @G B.

# Ruby, 34 28 bytes

->n{[-n,o=1e2].max/o+=n.abs}


Attempt This Online!

Thanks to @G B for saving 8 bytes!

I'm still learning Ruby, so this answer might be improvable, although @G B has improved it quite a bit already.

• 27 bytes
– MTN
Commented Sep 12, 2023 at 18:41
• @MTN What?? Why is 1e2 a float? Thanks for showing me something weird lol Commented Sep 12, 2023 at 22:42
• 26 bytes by using n+=1e2 instead of (1e2+n)
– G B
Commented Sep 13, 2023 at 15:07
• Also your original post can be shortened to 28: ->n{[-n,o=1e2].max/o+=n.abs}
– G B
Commented Sep 13, 2023 at 15:16
• @noodleman I can't think of a language where a literal expressed in scientific notation isn't a float
– c--
Commented Sep 13, 2023 at 16:10

# Vyxal, 55 bitsv2, 6.875 bytes

₁"sȧ¦ƒ/


Try it Online!

Port of Jelly.

# Vyxal, 50 bitsv2, 6.25 bytes

ȧ₁+/N1%


Try it Online!

Port of loopy walt's Python. It's longer in Jelly due to the argument order for division, but I intuited it would at least tie in Vyxal SBCS bytes, and it turns out it also Vyncodes marginally better.

 ₁+        Add 100 to
ȧ          the absolute value of n.
/       Divide n by that,
N      negate the result,
1%    and mod 1.


# Pip, 12 bytes

-a/(h+ABa)%1


Trivial implementation, 16 bytes.

(@YABSNgAEh)/$+y  Attempt This Online! # JavaScript (Babel Node), 25 bytes _=>(_>0?100:_=-_)/(100+_)  Try it online! # Excel, 30 bytes =1/(1+IF(A1<0,-100/A1,A1/100))  Input in cell A1. # Arturo, 34 bytes $->n[abs//(n<0)?->n[100]100+abs n]


Try it!

# R, 31 bytes

\(n)"if"(n<0,n<--n,100)/(100+n)


Attempt This Online!

# R, 31 bytes

\(n,z=sign(n))1/(1+(n/100)^z*z)


Attempt This Online!

I feel like one of these can be golfed down.

# J, 9 bytes

1|-%100+|


-5 bytes by porting loopy walt's answer!

Attempt This Online!

## J, original answer, 14 bytes

(100>.-)%100+|


Attempt This Online!

• 100>.- The larger of the negative of the input and 100
• % Divided by...
• 100+| 100 plus the absolute value of the input

My attempts to avoid repeating 100 led to longer solutions.

# Forth (gforth), 51 42 bytes

: f dup 100 min abs s>f abs 100 + s>f f/ ;


Try it online!

## Explanation

Originally, I used a conditional statement, but those use a lot of characters in gforth. I eventually realized that the goal is mostly just to determine what goes on top of the fraction, 100 or n. Since n will always be greater than 100 or less than -100, we can use min to get the value we want (if negative, n will always be less than 100, if positive, 100 will always be smaller).

## Code Explanation

: f         \ Begin word definition
dup       \ duplicate n on the top of the stack
100 min   \ take the smaller of n and 100
abs s>f   \ send the absolute value to the floating point stack
abs 100 + \ add 100 to the absolute value of n
s>f       \ move the result to the floating point stack
f/        \ divide the top two floating point stack values
;           \ end word definition

• Another rediscovery of @noodleman's original Ruby answer.
– Neil
Commented Sep 13, 2023 at 20:55

# Julia, 29 24 bytes

!n=mod(n/(~99-abs(n)),1)


Attempt This Online!

A port of loopy walt's solution.

mod is used (suggested by MarcMush), since Julia's default modulo % doesn't match Python's convention for negative numbers; using rem with rounding mode RoundDown would also work.

• I think mod would work instead of %|rem ? Commented Sep 15, 2023 at 21:58

# Python, 37 bytes

lambda n:(100,x:=abs(n))[n<0]/(100+x)


Attempt This Online!

# Octave / MATLAB, 30 bytes

@(n)min(100,n)/(n+100*sign(n))


# 05AB1E (legacy), 7 bytes

Äт+/(1%


Port of @loopyWalt's Python answer, so make sure to upvote that answer as well!

A port of @UnrelatedString's Jelly answer (in the new 05AB1E version) would be a byte longer:

т‚{ÄηO/


Explanation:

         #  Example inputs: +256               -256


Uses the legacy version of 05AB1E built in Python 3 for 1% to work. In the new version built in Elixir, it'll give incorrect results.

Ä        # Get the absolute value of the (implicit) input-integer
#                  256                256
т+      # Add 100 to it
#                  356                356
/     # Divide the (implicit) input by this abs(input)+100
#                  0.719...           -0.719...
(    # Negate it
#                  -0.719...          0.719...
1%  # (Python-style) modulo-1
#                  0.280...           0.719...
# (after which it's output implicitly as result)


Uses the new version of 05AB1E builtin Elixir for { to work. In the legacy version, it'll always keep the input first because it's seen as [string,integer] instead of [integer,integer].

т‚       # Pair the (implicit) input-integer with 100
#                  [256,100]          [-256,100]
{      # Sort this pair
#                  [100,256]          [-256,100]
Ä     # Get the absolute value of each
#                  [100,256]          [256,100]
η    # Get the prefixes of this pair
#                  [[100],[100,256]]  [[256],[256,100]]
O   # Sum each inner list
#                  [100,356]          [256,356]
# Pop and push both values separated to the stack
/ # Divide them from one another
#                  0.280...           0.719...
# (after which it's output implicitly as result)


# Charcoal, 18 bytes

ＮθＩ∕↔⌊⟦¹⁰⁰θ⟧⁺¹⁰⁰↔θ


Try it online! Link is to verbose version of code. Explanation: Turns out to be a port of @noodleman's original Ruby answer.

Ｎθ                  Input n as a number
¹⁰⁰          Literal integer 100
θ         Input n
⟦    ⟧        Make into list
⌊              Take the minimum
↔               Absolute value
∕                Divided by
¹⁰⁰    Literal integer 100
⁺       Plus
θ  Input n
↔   Absolute value
Ｉ                 Cast to string
Implicitly print


A slightly less accurate version is 16 bytes:

ＮθＩ∕χ⁺χ⌈⟦∕θχ±∕φθ


Try it online! Link is to verbose version of code. Explanation: "Illegal" positive odds and negative odds can be converted into "legal" odds by dividing into -10000, but we can also use this to convert all odds into positive odds and then use a modified version of the formula for those odds, the modification being 10/(10+n/10), since this is golfier in Charcoal.

Ｎθ                  First input as a number
χ               Predefined variable 10
∕                Divided by
χ             Predefined variable 10
⁺              Plus
θ         Input odds
∕          Divided by
χ        Predefined variable 10
φ     Predefined variable 1000
∕      Divided by
θ    Input odds
±       Negated
⟦           Make into list
⌈            Take the maximum
Ｉ                 Cast to string
Implicitly print


# Uiua, 10 bytes

◿1÷+100⌵.


Try it online!

Port of loopy walt's Python answer. If scored in UTF-8, beats the solution I wanted to post even harder because  autoformats to ¯ to save a single byte.

The solution I wanted to post:

# Uiua, 11 bytes

÷+,⊙⌵⊃↥↧100


Try it online!

Indirect port of my Jelly solution. A direct port comes out considerably longer due to scan/reduce operating right to left and it taking 3 characters to sort an array, but ⊃↥↧ fork max min sorts the top two values on the stack right in place on the stack, taking arrays out of the picture entirely... unfortunately also needing an extra ⊙ dip (or some restructuring and a : flip) to abs afterwards.

• Note that Uiua can be encoded using a single-byte character system (SBCS), so bytes==characters, and your intended solution (9 bytes) beats the Python port (10 bytes). Commented Oct 19, 2023 at 8:51
• The linked program in the answer can be used as a runnable implementation by simply prepending "&fwa "program.ua": the default behaviour of uiua is to autorun any file ending .ua in the current directory. Commented Oct 19, 2023 at 22:09
• As an example, here is my terminal encoding & decoding to a .ua file a uiua program to output the floor-sqrt of 10x 0 to 10... Commented Oct 19, 2023 at 22:19
• And here is the output of uiua (open in another terminal window) auto-running the .ua file as soon as it's created (or updated)... Commented Oct 19, 2023 at 22:20
• The 9 byter seems to be wrong with negative inputs. I think you missed A part in Jelly? Commented Oct 20, 2023 at 2:36

=mod(-A1/(abs(A1)+100),1)

Put the input in cell A1 and the formula in B1.

Uses mod() like the Python answer.

# Ruby, 21 bytes

Direct port of loopy walt's Python answer, for completeness.

->n{n/(-1e2-n.abs)%1}


Attempt This Online!

# C (GCC), 493634 33 bytes

f(n,r){r=(n?100:(n=-n))/(1e2+n);}


Saved a byte by negating n within the ternary and eliminating the abs call.

Attempt This Online!

f(n,r){r=(n?100:-n)/(1e2+abs(n));}


Changed 100.0 to 1e2 to save 2 bytes, since want 100 as float.

Attempt This Online!

f(n,r){r=(n?100:-n)/(100.0+abs(n));}


Changed the function name to a single char :P, used just n instead of n>0 in the ternary to check for positivity of the number n, used the out param r to store the return value.

Attempt This Online!

float golf(n){return(n>0?100:-n)/(100.0+abs(n));}


Attempt This Online!

This is my low effort attempt at golfing this problem using C. Need help!

• There's an opportunity to golf with removing the parentheses around the ternary. But I'm unsure about the precedence and feeling lazy to check myself. Commented Sep 14, 2023 at 13:20