近似点数


17

蒂数是余弦函数的固定点,或溶液等式COS(X)= X1个

您的任务是制作近似于该常数的代码。您的代码应代表一个接受整数作为输入并输出实数的函数。随着输入的增加,功能的极限应为Dottie数。

您可以输出数字的分数,小数或代数形式。您的输出应该能够任意精确,浮点和双精度不足以应对这一挑战。如果您的语言不支持任意精度数字,则必须实现它们或选择一种新的语言。

这是一个问题,因此答案将以字节计分,而字节越少越好。

提示

一种计算常数的方法是取任意数字并对其重复应用余弦。随着应用次数趋于无穷大,结果趋向于余弦的固定点。

这是一个相当准确的数字近似值。

0.739085133215161

1:在这里我们将以弧度表示余弦


因此,如果我们使用Python,则必须实现自己的类型或import Decimal
Xcoder先生17年

我们提交的内容必须有多准确?
Xcoder先生17年

去果冻教程偷了ÆẠȷ¡意识到是无效的。尝试Brachylog; 哦,没有Brachylog甚至都没有浮标。
暴民埃里克(Erik the Outgolfer)'17

1
我觉得“任意精确”的要求太严格了。为什么不认为答案一次有效x=cos(x)
kamoroso94 '17

2
我希望在Haskell,APL和一些Lisp风格中看到它。
Mark C

Answers:


7

MATL34 30 19字节

感谢Sanchises节省了 11个字节!

48i:"'cos('wh41hGY$

输出中的最后一个十进制数字可能会关闭。但是,从左侧开始的正确数字的数量随输入而增加,结果收敛到实际常数。

在线尝试!

说明

对于输入n,从x = 1开始,这将应用函数

              X ↦COS(X

使用n可变精度算术 n次。

48         % Push 48, which is ASCII for '1': initial value for x as a string
i:"        % Do n times, where n is the input
  'cos('   %   Push this string
  w        %   Swap. Moves current string x onto the top of the stack
  h        %   Concatenate
  41       %   Push 41, which is ASCII for ')'
  h        %   Concatenate. This gives the string 'cos(x)', where x is the
           %   current number
  GY$      %   Evaluate with variable-prevision arithmetic using n digits
           %   The result is a string, which represents the new x
           % End (implicit). Display (implicit). The stack contains the last x

为什么不以n位精度将其应用n次呢?这似乎过于复杂。
桑奇斯

1
这难以置信。我想在APL中看到它。
Mark C


4

GNU bc -l,30岁

分数包括+1 -l标记bc

for(a=1;a/A-b/A;b=c(a))a=b
a

最后的换行符很重要且必要。

在线尝试

-l 做两件事:

  • 启用“数学”库,包括c()cos(x)
  • 将精度(小数位)设置为小数点后20位(bc具有任意精度计算)

我对精度要求还不太清楚。照原样,此程序计算到小数点后20位。如果需要不同的精度,则scale=n;需要在程序的开始处插入,这里n是小数位数。我不知道是否应该将此添加到我的分数中。

还要注意,对于某些小数位数(例如21,但不是20),计算将在最后一位数字中振荡解决方案的任一边。因此,在比较当前迭代和先前迭代时,我将两侧除以10(A)以擦除最后一位。


4

Mathematica,22个字节

Nest[Cos@#&,0,9#]~N~#&

输入

[100]

输出

0.73908513321516064165531208767387340401341175890075746496568063577328 \ 46548835475945945993761069317665318



3

K:6个字节

  _cos/1
0.7390851

f/适用f直到它到达一个固定的点。


这是什么版本的k?_我知道的大多数版本都是地板。在K4和OK,你可以得到5个字节cos/1
乱写

K3。内置项从下划线开始。
tangentstorm

1
有趣!我没有在野外看到k3。因为有比这个论坛:)用两个版本的更多可能是值得诬指这样
乱写

2

R(+ Rmpfr),55个字节

function(n,b=Rmpfr::mpfr(1,n)){for(i in 1:n)b=cos(b);b}

丹尼斯现在已将Rmpfr添加到TIO中,因此它将起作用。添加了一些测试用例。

说明:

注意到我从写的代码这一挑战,以评估cos n开始的时间1,但首先我指定我想要的值通过创建一个对象是在精密bmpfr与价值1和精确度nn>=2,所以我们得到更精确,因为我们走。

在线尝试!


3
再试一次。:)将来,如果TIO缺少任何内容,请立即在talk.tryitonline.net中发送消息。
丹尼斯

@丹尼斯,谢谢!以后我会记住这一点!
朱塞佩


2

dzaima / APL,55字节

⎕←⊃{⍵,⍨-/P,((P÷⍨×)/¨(2×⍳N)⍴¨⊃⍵)÷!2L×⍳N}⍣{⍵≢∪⍵}P10L*N←⎕

10N1NN

没有TIO链接,因为尚未更新TIO的dzaima / APL以支持bigintegers。

I / O示例:

1
9L

10
7390851332L

100
7390851332151606416553120876738734040134117589007574649656806357732846548835475945993761069317665318L

200
73908513321516064165531208767387340401341175890075746496568063577328465488354759459937610693176653184980124664398716302771490369130842031578044057462077868852490389153928943884509523480133563127677224L


1

Pyth57 54字节

u_.tG1lX$globals()$"neg"$__import__("decimal").Decimal

如果我们不需要十进制数来符合规范,则时间会短得多,但这就是事实。

编辑1:-3个字节,因为无论如何我们都需要一个数字,因此我们可以使用Xs返回的globals()length 副本作为我们的起始值,将其移动到末尾并删除a $和一些空格。

在线尝试!


1

APL(Dyalog Unicode),9个字节

2○⍣=1

在线尝试!

注意:TIO有一个附加项⎕←;TIO 对此是必需的。“独立的” APL解释器将使用上面显示的精确表达式。给出的字节数是TIO为上面的表达式计算的,而不是带。的字节数⎕←

分解/说明:

2○⍣=1
            Apply repeatedly the function...
2           ...cosine of x (in radians), such that...
    1        ...the initial value of x is 1, and...
   =         ...if cos x is NOT equal to x, then re-evaluate, substituting cos x for x...
             ...until they ARE equal.

第一次评估函数cos x(2○x)且x = 1时,它们将不相等。cos 1为0.5403 ...,因此重新评估,将0.5替换为1,然后重复该过程直到(2○x)= x,对于x = 0.73908发生。

在创建此设置时,我使用了“打印精度”的默认值,可以使用canPP←在APL中进行设置;Dyalog APL允许的⎕PP的最大值为34位数字。

同样,此实现的默认精度为64位浮点数;通过设置⎕FR←1287可以使用128位浮点数。TIO计算是通过64位浮点数完成的。

计算机语言的任何实际实现都不能真正赋予任意精度。然而,对于一个理论APL,代码执行任意精度将是完全一样的


这是5个字节。
阿达姆

正如您在聊天中提到的那样,这应该是NARS2000解决方案,在Dyalog中无效。然后,要使其输入正确,应设置⎕CT←0,并可能将输入分配给⎕FPC
dzaima

这不支持任意精度,这是规范所要求的:Your output should be capable of being arbitrarily precise, floats and doubles are not sufficient for this challenge.
Grimmy


0

Perl 5,41字节

use bignum;sub f{$_[0]?cos(f($_[0]-1)):0}

Bignum是任意精度所必需的。定义一个函数f,该函数递归地将余弦应用于0 N次。

TIO似乎没有bignum,所以没有链接:(



0

Python 2,86个字节

import math as m,decimal as d
def f(x,n):return f(d.Decimal(m.cos(x)),n-1)if n else x

使用提供的技巧的新版本。

Python 2,105个字节

import math as m,decimal as d
def f(x,n):return d.Decimal(f(x+(m.cos(x)-x)/(m.sin(x)+1),n-1))if n else x

使用 牛顿方法和递归函数来计算值。x是初始值,n是递归限制。


Python的内置float类型确实具有不确定的精度,因此您的函数实际上并不是渐近的。
Ad Hoc Garf Hunter

谢谢,很高兴知道。固定,我猜,不是很短了:)
SydB

问题中提供的提示可能比牛顿的方法短。
Ad Hoc Garf Hunter

再次感谢,似乎我对花哨的数学太着迷了。
SydB

n根据要求,您的函数应仅接受1个参数,因此您需要使用default x=0。同样,此功能也不是任意精确的,因为它math.cos是固定的精度。
痰痰

0

公理,174字节

f(n:PI):Complex Float==(n>10^4=>%i;m:=digits(n+10);e:=10^(-n-7);a:=0;repeat(b:=a+(cos(a)-a)/(sin(a)+1.);if a~=0 and a-b<e then break;a:=b);a:=floor(b*10^n)/10.^n;digits(m);a)

取消评论

-- Input: n:PI numero di cifre
-- Output la soluzione x a cos(x)=x con n cifre significative dopo la virgola
-- Usa il metodo di Newton a_0:=a  a_(n+1)=a_n-f(a_n)/f'(a_n)
fo(n:PI):Complex Float==
  n>10^4=>%i
  m:=digits(n+10)
  e:=10^(-n-7)
  a:=0     -- Punto iniziale
  repeat
     b:=a+(cos(a)-a)/(sin(a)+1.)
     if a~=0 and a-b<e then break
     a:=b
  a:=floor(b*10^n)/10.^n
  digits(m)
  a

结果:

(3) -> for i in 1..10 repeat output[i,f(i)]
   [1.0,0.7]
   [2.0,0.73]
   [3.0,0.739]
   [4.0,0.739]
   [5.0,0.73908]
   [6.0,0.739085]
   [7.0,0.7390851]
   [8.0,0.73908513]
   [9.0,0.739085133]
   [10.0,0.7390851332]
                                                               Type: Void
           Time: 0.12 (IN) + 0.10 (EV) + 0.12 (OT) + 0.02 (GC) = 0.35 sec
(4) -> f 300
   (4)
  0.7390851332 1516064165 5312087673 8734040134 1175890075 7464965680 635773284
  6 5488354759 4599376106 9317665318 4980124664 3987163027 7149036913 084203157
  8 0440574620 7786885249 0389153928 9438845095 2348013356 3127677223 158095635
  3 7765724512 0437341993 6433512538 4097800343 4064670047 9402143478 080271801
  8 8377113613 8204206631
                                                      Type: Complex Float
                                   Time: 0.03 (IN) + 0.07 (OT) = 0.10 sec

我将使用牛顿法,因为它比“重复cos(x)法”更快

 800   92x
1000  153x
2000  379x

在第一列中有位数,在第二列中有牛顿法比使用重复cos(x)法要快多少。早上好


0

Stax,5 个字节

╘ñ[EΩ

运行并调试它的解释

1       Push 1 to the stack, this will be our initial variable
 {      Begin block
  |7    Cosine
    }N  Repeat block a number of times specified by the input

1
这不支持任意精度,这是规范所要求的:Your output should be capable of being arbitrarily precise, floats and doubles are not sufficient for this challenge.
Grimmy

0

JavaScript(Node.js),84字节

n=>"0."+(F=(J,Z=c=0n)=>J?F(J*-I*I/++c/++c/B/B,Z+J):I-Z>>2n?(I=Z,F(B)):I)(B=I=10n**n)

在线尝试!

具有大约n-1几位的精度。使用BigInt并cos(x)使用其泰勒展开式进行计算。该I-Z>>2n部件仅用于永久防止循环(代价为4字节和某些精度)。尽管理论上适用于任意精度,但实际范围是n<63由于堆栈溢出。

较短(82字节),无需担心堆栈溢出,但精度要低得多

n=>"0."+eval("for(I=B=10n**n;n--;I=Z)for(Z=J=B,c=0n;J;)Z+=(J=J*-I*I/++c/++c/B/B)")

短得多(80字节),范围更大,直到堆栈溢出(n<172),但精度与82字节相同。

n=>"0."+(F=(J,Z=c=0n)=>J?F(J*-I*I/++c/++c/B/B,Z+J):n--?(I=Z,F(B)):I)(B=I=10n**n)

如果任意精度不是重点,则为25个字节:

F=n=>n?Math.cos(F(n-1)):1
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.