g | x | w | all
Bytes Lang Time Link
020APLNARS251005T080410ZRosario
162Python 3210406T044610Zhyperneu
074Retina210406T193515ZNeil
069Haskell210406T150840ZDelfad0r
080R210406T114928ZKirill L
038Charcoal210406T113945ZNeil
067JavaScript ES6210406T065143ZArnauld
047Wolfram Language Mathematica210406T054220ZZaMoC
014Stax210406T045105ZRazetime
2523J210406T051342ZJonah

APL(NARS), 20 chars

{↑k/⍨⍺≥÷1∨¨k←⌽+∘÷\⍵}

Input ⍺ one positive integer, ⍵ one array of elements rational type. Output one rational.

↑k/⍨⍺≥÷1∨¨k←⌽+∘÷\⍵
    ⍺            ⍵  ⍺ is the input left, ⍵ is the input right 
             +∘÷\⍵  this would make +∘÷/⍵ save each '+∘÷ partial sums' in a array of rational numbers
          k←⌽       this would reverse the array of rationals found, and put that array in the k variable
                      note that here in k each element has a better approximation of the input ⍵
                      than the next in the array k.
      ÷1∨¨          this would find each denominator of the array of rationals k, and return the array of them
    ⍺≥              this would build one boolean array ⍺≥denominators   
↑k/⍨                this would get the first in the array k that has denominator with ⍺≥denominator
                    so it return the better approximation of the number in ⍵ that has ⍺≥denominator

The array of rational type it seems can be defined write one "x" after the first element of the array.

test:

 f←{↑k/⍨⍺≥÷1∨¨k←⌽+∘÷\⍵}
 43 f 0x 2 3 6 1 3 3 
3r7 
 44 f 0x 2 3 6 1 3 3 
19r44 
 99 f 5x 6 7  
222r43 
 43 f ,1x  
1
  1 f ,1x  
1 
  1 f 0x 2 3 6 1 3 3 
0 

Python 3, 162 bytes

lambda x,y:min((abs(q-g(*x)),q)for q in[g(*x[:i+1])for i in range(len(x))]if q.denominator<=y)[1]
g=lambda v,*k:v+Fraction(*k and(1,g(*k)))
from fractions import*

Try it online!

-28 bytes thanks to ovs

Retina, 74 bytes

,
¶$%`,
¶
/1¶
+`\d+,(\d+)/(.+)
$.($2*_$1**)/$1
N$r`.*(\d+)
$1
L`.+¶(?!.+/)

Try it online! Takes the continued fraction and denominator on separate lines, but link includes test suite that splits on ; for convenience. Explanation:

,
¶$%`,

Get all prefixes of the continued fraction.

¶
/1¶

Start each prefix with a denominator of 1.

+`\d+,(\d+)/(.+)
$.($2*_$1**)/$1

Calculate each resulting rational number from right to left.

N$r`.*(\d+)
$1

Sort the desired denominator into the list of rational numbers.

L`.+¶(?!.+/)

Output the rational number whose denominator is the largest that does not exceed the desired denominator.

Haskell, 70 69 bytes

x?m=last[y|y<-f x,y!!1<=m]
f(h:t)=[h,1]:[[a*h+b,a]|[a,b]<-f t]
f[]=[]

Try it online!

The relevant function is (?), which takes as input the continued fraction x (as a list of integers) and the maximum denominator m. The output is a list of integers [numerator,denominator].

How?

x?m=            -- x=continued fraction, y=maximum denominator
  last[         -- return the last
    y|y<-f x,   --   convergent of x
    y!!1        --   whose denominator (i.e. second element)
      <=m       --     is at most m
  ]
f                   -- helper function for computing convergents
  (h:t)=            --   h=first number, t=rest of the continued fraction
    [h,1]:          --     the first convergent is h (i.e. h/1)
    [[a*h+b,a]      --     the other convergents are h+b/a (i.e. (a*h+b)/a)
      |[a,b]<-f t]  --       where a/b ranges over the convergents of t
f[]=[]              -- base case for the empty continued fraction

R, 88 80 bytes

function(x,y,`~`=cbind,z=1:0~0:1){for(i in x)z=z[,1]*i+z[,2]~z;z[,z[2,]<=y][,1]}

Try it online!

Charcoal, 38 bytes

FLθ«≔⟦§θι¹⟧ζF⮌…θι≔⁺⁺⊟ζ×ζκζζ¿¬›§ζ¹ηP⪫ζ/

Try it online! Link is to verbose version of code. Explanation:

FLθ«

Loop over the prefixes.

≔⟦§θι¹⟧ζ

Form a "fraction" of the current element.

F⮌…θι

Loop over the preceding elements.

≔⁺⁺⊟ζ×ζκζζ

Invert the fraction and add on the element. This is some decidedly tricky coding. The old denominator is popped from the fraction, leaving behind the old numerator as a list of one element. This is vectorised multiplied by the element and added to the denominator, thus making a list of just the new numerator. The old numerator, still in its list, is then list concatenated to it, where it becomes the new denominator.

¿¬›§ζ¹ηP⪫ζ/

If the denominator is still small enough, overprint the previous fraction (if any) with the current fraction.

JavaScript (ES6),  72 68   67 bytes

Expects (max_denominator)(seq). Returns [numerator, denominator].

m=>g=([v,...a],n=0,d=1,N=1,D=0)=>(d+=D*v)<=m?g(a,N,D,N*v+n,d):[N,D]

Try it online!

Commented

m =>             // outer function taking m = maximum denominator
g = (            // inner recursive function taking:
  [v,            //   v = next term from the continued fraction
      ...a],     //   a[] = remaining terms
  n = 0,         //   n = previous numerator
  d = 1,         //   d = previous denominator
  N = 1,         //   N = current numerator
  D = 0          //   D = current denominator
) =>             //
  (d += D * v)   // we compute the new denominator d = D * v + d
                 // this results in NaN if v is undefined,
                 // which forces the comparison to fail
  <= m ?         // if it's less than or equal to m:
    g(           //   do a recursive call:
      a,         //     pass the remaining terms of the continued fraction
      N, D,      //     pass the current numerator and denominator
      N * v + n, //     pass the new numerator
      d          //     pass the new denominator
    )            //   end of recursive call
  :              // else:
    [N, D]       //   we're done: return [N, D]

Wolfram Language (Mathematica), 47 bytes

Last@*Cases[a_/;Denominator@a<=#]@*Convergents&

Try it online!

-25 bytes from @att

Stax, 14 bytes

╪£pÇUßi⌂Ω♫M⌂░◘

Run and debug it

takes inputs as <max denominator>,<continued fraction>.

Explanation

|[{r{su+km{Rn^<oH
|[{      m        for each prefix of the continued fraction
   r               reverse
    {   k          reduce by:
     su+            swap, reciprocal and add
          {    o  order by:
           R       denominator
            n^<    lesser than 2nd input + 1 ? 
                H last element

J, 25 23 bytes

(]{:@#~0#.>:)2 x:(+%)/\

Try it online!

-2 thanks to Bubbler

how

We'll use 43 f 0, 2, 3, 6, 1, 3, 3x as an example...