Input
Two non-negative floating point numbers \$x < y\$. You can assume they are close enough to each other that there is no integer between \$x\$ and \$y\$.
Output
A fraction with the smallest possible denomination that lies strictly between \$x\$ and \$y\$.
Examples
Input: 1 and 2
Output: 3/2
Input: 0 and 0.33
Output: 1/4
Input: 0.4035 and 0.4036
Output: 23/57
6 Answers 6
JavaScript (Node.js), 42 bytes
x=>g=(y,d)=>(p=-~(x*d))<y*d?[p,d]:g(y,-~d)
If \$ \left \lfloor xd \right \rfloor +1 < yd \$, then \$ \left \lfloor xd \right \rfloor +1 \$ is an answer
-
\$\begingroup\$ Which is fortunate since
⌈xd⌉<ydis the wrong test. \$\endgroup\$Neil– Neil2024年01月12日 23:49:45 +00:00Commented Jan 12, 2024 at 23:49
JavaScript (ES6), 47 bytes
Expects (x)(y), returns [numerator, denominator].
(x,p=q=1)=>g=y=>p<y*q++&&p++>x*--q?[--p,q]:g(y)
Commented
( x, // x = first number
p = // p = numerator
q = 1 // q = denominator
) => //
g = y => // y = second number
p < y * q++ // we test whether p/q < y
// and increment q afterwards in case it's not
&& // if truthy,
p++ > x * --q // we restore q, test whether p/q > x
// and increment p afterwards in case it's not
? // if truthy again:
[--p, q] // we restore p and return [p, q]
: // else:
g(y) // we try again with either p or q incremented
-
\$\begingroup\$ But how does it work? \$\endgroup\$Simd– Simd2024年01月12日 22:37:03 +00:00Commented Jan 12, 2024 at 22:37
-
\$\begingroup\$ @Simd I've added a commented version. This is a really simple algorithm, but written in a slightly convoluted way. \$\endgroup\$Arnauld– Arnauld2024年01月12日 22:56:36 +00:00Commented Jan 12, 2024 at 22:56
Charcoal, 33 bytes
×ばつηζζ
Try it online! Link is to verbose version of code. Explanation:
NθNη
Input x and y.
×ばつθι2ζ
Find d such that ⌈yd⌉-⌊xd⌋=2. d is never more than ⌊1+1/(y-x)⌋, but I have to add 2 due to 0-indexing.
×ばつηζζ
Output ⌈yd⌉-1 and d.
Jelly, 18 bytes
×ばつḞĊƭ€r/ḊṖ
1ç1#Ḣṭç\
A pair of links which is called as a monad with a pair of floats and returns a pair of [numerator, denominator].
Explanation
×ばつḞĊƭ€r/ḊṖ | Helper link: takes a denominator as the left argument and a pair of floats as the right and returns a valid numerator, if an×ばつ | Multiply (denominator with floats)
ḞĊƭ€ | Floor first, ceiling second
r/ | Reduce using range
ḊṖ | Remove first and last
1ç1#Ḣṭç\ | Main link
1ç1# | Starting with one, find first denominator where there’s a valid numerator (will be wrapped in a list)
Ḣ | Head (to unwrap the list)
ṭç\ | Tag this onto the result of running the helper link again to find the numerator
```
Python 2, 95 bytes
(a,b),(c,d)=[input().as_integer_ratio()for m in 0,0]
while(m*d/c+1)*a>=m*b:m+=1
print m,m*d/c+1
Not a math guy, basically uses the formula of this answer.
The input should be in decimal format: 1.0 instead of just 1.
-2 bytes: replace // with /
-4 bytes: inlining m
0.3333333333333333148..., is the fraction 1/3 greater than that? \$\endgroup\$