# Rational Number RNG

## JavaScript (ES6), 81 bytes

Returns $$\p/q\$$ as [p,q].

f=(p=0,q=1)=>Math.random()<(g=(a,b)=>b?g(b,a%b):a)(p,q)/2?f(++p-q?p:!++q,q):[p,q]


Try it online!

Or Try some statistics!

### How?

We recursively build the fractions $$\p/q\$$ in the relevant order, but without any explicit deduplication, until a random number picked in $$\[0,1[\$$ is greater than or equal to $$\gcd(p,q)/2\$$.

If $$\p\$$ and $$\q\$$ are not coprime, we have $$\gcd(p,q)/2\ge1\$$, which always triggers the recursive call. This is the expected behavior because the corresponding fraction must be discarded.

If $$\p\$$ and $$\q\$$ are coprime, we have $$\gcd(p,q)/2=1/2\$$, which is the desired probability of triggering the next call.

### Commented

f = (                 // f is a recursive function taking:
p = 0,              //   p = numerator, starting at 0
q = 1               //   q = denominator, starting at 1
) =>                  //
Math.random() <     // pick a random number in [0,1[
(g = (a, b) =>      // g is a recursive function computing the gcd of 2 integers
b ?               //   if b is not equal to 0:
g(b, a % b)     //     recursive call with (b, a mod b)
:                 //   else:
a               //     return a
)(p, q) / 2 ?       // if our random number is less than gcd(p, q) / 2:
f(                //   do a recursive call:
++p - q ? p     //     increment p if p < q - 1
: !++q, //     otherwise: set p to 0 and increment q
q               //
)                 //   end of recursive call
:                   // else:
[p, q]            //   stop recursion and return [p, q]


## Ruby, 74 67 bytes

Probably not the golfiest solution for Ruby, but it was the first thing that sprung to mind. Increment the counter $. (starts at 0) each time rand is at least 0.5 to determine the index, then determine the list of rationals and output the right one. -7 bytes from histocrat. d,*a=1r$.+=1until rand<0.5
a|=(0...d+=1).map{|n|n/d}until p *a[$.]  Try it online! ## Julia, 6149 71 bytes p>q=rand()<.5 ? (p<q-1 ? (while gcd(p+=1,q)!=1 end;p>q) : 1>q+1) : p//q  In un-golfed form, this reads function f(p,q) # define the function if rand() < 0.5 # flip a coin. if p < (q - 1) # if the coin gives heads, check if p < (q - 1) while gcd(p+1, q) != 1 # if the greatest common divisor or p+1 and q is not equal to 1 p = p + 1 # we increment p, because otherwise we'd get a fraction we already saw. end return f(p, q) # recursively call f(p, q) (where p has been incremented) else return f(1, q+1) # if p is not greater than q - 1, we recursively call f(1, q+1) end else return p//q # If the coin flip gives tails, we return the Rational number p//q end end  Now let's check to make sure we did this right: julia> using UnicodePlots; data = [0>1 for _ in 1:10_000_000]; histogram(data) ┌ ┐ [0.0 , 0.05) ┤▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 5000106 [0.05, 0.1 ) ┤ 0 [0.1 , 0.15) ┤ 1168 [0.15, 0.2 ) ┤▇ 82600 [0.2 , 0.25) ┤ 0 [0.25, 0.3 ) ┤▇▇ 313684 [0.3 , 0.35) ┤▇▇▇▇▇▇▇▇ 1250427 [0.35, 0.4 ) ┤ 39124 [0.4 , 0.45) ┤ 310 [0.45, 0.5 ) ┤ 0 [0.5 , 0.55) ┤▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 2498798 [0.55, 0.6 ) ┤ 168 [0.6 , 0.65) ┤ 19403 [0.65, 0.7 ) ┤▇▇▇▇ 625484 [0.7 , 0.75) ┤ 77 [0.75, 0.8 ) ┤▇ 166131 [0.8 , 0.85) ┤ 2473 [0.85, 0.9 ) ┤ 47 └ ┘ Frequency julia> for frac in [(0//1), (1//2), (1//3), (2//3), (1//4), (3//4), (1//5), (2//5), (3//5), (4//5), (1//6), (5//6)] freq = count(x -> x == frac, data)/length(data) println("P($(frac)) ≈ \$freq")
end
P(0//1) ≈ 0.5000106
P(1//2) ≈ 0.2498798
P(1//3) ≈ 0.1250427
P(2//3) ≈ 0.0625484
P(1//4) ≈ 0.0313065
P(3//4) ≈ 0.0156477
P(1//5) ≈ 0.0077772
P(2//5) ≈ 0.0039116
P(3//5) ≈ 0.0019398
P(4//5) ≈ 0.0009654
P(1//6) ≈ 0.0004828
P(5//6) ≈ 0.0002473


Notice that P(5//6) ≈ 0.5 * P(1//6) as required since 2//6, 3//6, and 4//6 are reducible fractions.

Try it online!