10
\$\begingroup\$

Inspired by How to write down numbers having an infinity of decimals? Link 🇫🇷

Background

From Wikipedia: for almost all real numbers \$x\$, coefficients \$a_i\$ of the continued fraction expansion of \$x\$ have a finite geometric mean that is independent of the value of \$x\$ and is known as Khinchin's Constant.

Khinchin's Constant can be calculated using the following method:

  1. Using the \$n\$ first terms of the simple continued fraction of a real number (For example Pi).
  2. Compute their product
  3. Apply the \$n^{\text{th}}\$ root on the absolute value of product calculated above

What is a simple continued fraction

It can be expressed as: $$x=[a_0; a_1, a_2, \dots, a_n]$$ Or $$ x=a_0+ \cfrac{1}{a_1+ \cfrac{1}{a_2+ \cfrac{1}{\ddots{+ \cfrac{1}{a_n}}}}} $$

And can be calculated using the following:

  1. Separate \$x\$ into its integer part \$a_n\$ and decimal part \$d\$
    • \$a_n = \lfloor x \rfloor\$
    • \$d = x - \lfloor x \rfloor\$
  2. Repeat using the inverse of \$d\$ in place of \$x\$ while \$d\$ is not 0

It is a simple continued fraction because the numerator is always 1.

For negative numbers, the same rule applies, the first term of the sequence will be negative.

For example for \$π\$: $$ π = [a_0; a_1, a_2, a_3, \dots] = [3; 7, 15, 1, 292, \dots] $$

$$ π=3+\cfrac{1}{7+ \cfrac{1}{15+ \cfrac{1}{1+ \cfrac{1}{292+ \cdots}}}} $$

And \$-π = [-4; 1, 6, 15, 1, 292, \dots]\$

Challenge

Using the method used to approximate Khinchin's Constant described above:
Given a number of terms \$n\$ and a real number \$x\$, compute the geometric mean of the coefficients of the continued fraction expansion of \$x\$.

Standard rules apply.

Test cases:

Terms to use Real number Expected Result Note
1 π 3
2 π 4.5825...
3 π 6.8040...
7 π 5.1179...
7 -π 5.2165...
15 1.8156...
15 - 1.9164...
20 -φ 1.0717...
20 φ 1
100 φ 1 Optional, might not work because of consecutive floating point errors

Scoring

This is , so the answer with the least amount of bytes wins.

\$\endgroup\$
24
  • 1
    \$\begingroup\$ Can we work with floating-point numbers and accept some small inaccuracy derived from that? \$\endgroup\$
    – Luis Mendo
    Sep 29 at 22:05
  • 1
    \$\begingroup\$ Which invalidates my answer. \o/ \$\endgroup\$
    – Arnauld
    Sep 29 at 22:08
  • 4
    \$\begingroup\$ I think the problem with phi using floating-point numbers may be in defining the input, rather than in the computations. phi cannot be defined exactly as a floating-point value \$\endgroup\$
    – Luis Mendo
    Sep 29 at 22:39
  • 3
    \$\begingroup\$ Being pedantic, the challenge isn’t to calculate Khinchin’s constant but rather the (related) geometric mean of the coefficients of the continued fraction expansion of \$x\$. According to Wikipedia, \$\phi\$ and \$e\$ are among the exceptions to the ‘almost all’ clause: the geometric means for these numbers do not converge to Khinchin’s constant. None of this changes the task as specified, but perhaps the wording could be clarified. \$\endgroup\$
    – Dingus
    Sep 29 at 23:39
  • 2
    \$\begingroup\$ To add to Luis Mendo's comment, I believe that -pi has a very different continued fraction expansion from pi if we adhere to wikipedia's definition, so (7,-pi) should give a very different answer from (7,pi). \$\endgroup\$
    – Bubbler
    Sep 30 at 12:50
4
\$\begingroup\$

Husk, 14 bytes

^\¹Π↑¡§,o\%1⌊²

Try it online! for the last test case (or try it here for n=7, number=pi).

     ¡          # Apply function repeatedly to first results, 
                # collecting second results into infinite list:
      §,     ²  #  combine pair of results of functions applied to arg 2:
            ⌊   #   floor
        o\%1    #   reciprocal of fractional part
    ↑           # Now take arg1 elements from list,
   Π            # calculate the product,
^               # and raise to the power of
 \¹             # reciprocal of arg1
\$\endgroup\$
4
\$\begingroup\$

Factor + math.continued-fractions math.unicode, 66 bytes

[ 1vector over [ dup next-approx ] times 1 head* Π abs nth-root ]

Try it online!

Explanation

It's a quotation (anonymous function) that takes an integer signifying the number of terms to use and a real number and returns a real number. Assuming 3 3.141592653589793 is on the data stack when this quotation is called...

Snippet Comment Data stack (top on right)
1vector Make a vector out of the object on top of the data stack. This is how next-approx expects to take its input. 3 V{ 3.141592653589793 }
over Put a copy of the object second from the top on top of the data stack. 3 V{ 3.141592653589793 } 3
[ dup next-approx ] Push a quotation to the data stack for times to use later. 3 V{ 3.141592653589793 } 3 [ dup next-approx ]
times Take an integer and a quotation and call the quotation that many times. In this case, equivalent to dup next-approx dup next-approx dup next-approx
Inside the quotation now... 3 V{ 3.141592653589793 }
dup Copy the top data stack object 3 V{ 3.141592653589793 } V{ 3.141592653589793 }
next-approx Add the next term in the continued fraction to our vector. next-approx has stack effect ( seq -- ) so we made a copy so we don't lose it 3 V{ 3 7.062513305931052 }
dup next-approx Iteration 2 3 V{ 3 7 15.9965944066841 }
dup next-approx Iteration 3 3 V{ 3 7 15 1.003417231015 }
1 head* Remove last element 3 V{ 3 7 15 }
Π Take the product 3 315
abs Take the absolute value 3 315
nth-root Take the nth root of a number. In this case, take the cube root of 315 6.804092115953367
\$\endgroup\$
3
\$\begingroup\$

Mathematica, 42 38 bytes

N@1##&@@ContinuedFraction[#2,#]^(1/#)&

Corrected formatting and size reduced by @theorist.

Inputting n=100 and variable as Pi we get the output as

2.69405

You can save 2 bytes by removing N@ but this will give an exact expression and not numeric.

The code also passes all the tests giving the exact value for each number except for -Pi for which it returns a complex number. However the magnitude of this complex number is exactly the same as that given in the expected value.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ For this site, you'll want to format your code as a program that can take the arguments as input, e.g.: N@1##&@@ContinuedFraction[#2,#]^(1/#)& (38 bytes). This would be implemented as: N@1##&@@ContinuedFraction[#2,#]^(1/#)&@@{n,x}, e.g., N@1##&@@ContinuedFraction[#2,#]^(1/#)&@@{100,Pi} \$\endgroup\$
    – theorist
    Sep 30 at 6:55
  • 1
    \$\begingroup\$ You can remove the whitespace \$\endgroup\$
    – pxeger
    Sep 30 at 6:57
  • \$\begingroup\$ Thanks. I'll fix the formatting. \$\endgroup\$ Sep 30 at 6:58
2
\$\begingroup\$

JavaScript (ES7), 47 bytes

Expects (n)(real).

n=>v=>(g=n=>n?~~v*g(n-1,v=1/(v%1)):1)(n)**(1/n)

Try it online!

Note: With 40+ terms, the last test case will diverge from 1 because of cumulated floating point errors.

\$\endgroup\$
1
\$\begingroup\$

Ruby, 57 bytes

->n,l,r=1{n=n.abs;l.times{r*=n.to_i**(1.0/l);n=1/n%=1};r}

Try it online!

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.