Aproximar el número de Dottie


13

El número de Dottie es el punto fijo de la función coseno, o la solución a la ecuación cos (x) = x . 1

Su tarea será hacer un código que se aproxime a esta constante. Su código debe representar una función que toma un número entero como entrada y genera un número real. El límite de su función a medida que crece la entrada debe ser el número Dottie.

Puede generar una fracción, un decimal o una representación algebraica de un número. Su salida debe ser capaz de ser arbitrariamente precisa, los flotadores y los dobles no son suficientes para este desafío. Si su idioma no es capaz de números de precisión arbitrarios, debe implementarlos o elegir un nuevo idioma.

Esta es una pregunta de , por lo que las respuestas se puntuarán en bytes, con menos bytes mejor.

Consejos

Una forma de calcular la constante es tomar cualquier número y aplicarle repetidamente el coseno. Como el número de aplicaciones tiende hacia el infinito, el resultado tiende hacia el punto fijo del coseno.

Aquí hay una aproximación bastante precisa del número.

0.739085133215161

1: Aquí tomaremos coseno en radianes


Entonces, si estamos usando Python, ¿debemos implementar nuestro propio tipo o importar Decimal?
Sr. Xcoder

¿Qué tan precisas deben ser nuestras presentaciones?
Sr. Xcoder

Va al tutorial de Jelly para robar y se ÆẠȷ¡da cuenta de que no es válido. Intenta Brachylog; oh no, Brachylog ni siquiera hace carrozas.
Erik the Outgolfer

@ Mr.Xcoder Solo deben ser asintóticamente precisos.
Post Rock Garf Hunter

1
Me gustaría ver esto en Haskell, APL y un poco de sabor Lisp.
Mark C

Respuestas:


6

MATL , 34 30 19 bytes

¡11 bytes de descuento gracias a Sanchises !

48i:"'cos('wh41hGY$

Las últimas cifras decimales en la salida pueden estar apagadas. Sin embargo, el número de cifras correctas a partir de la izquierda aumenta con la entrada, y el resultado converge a la constante real.

Pruébalo en línea!

Explicación

Para la entrada n , y comenzando en x = 1, esto aplica la función

              x ↦ cos ( x )

con aritmética de precisión variable de n dígitos n veces.

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

¿Por qué no solo aplicarlo n veces con precisión de n dígitos? Esto parece demasiado complicado.
Sanchises

Esto es increíble. Quiero verlo en APL.
Mark C



3

GNU bc -l, 30

La puntuación incluye +1 para la -lbandera bc.

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

La nueva línea final es significativa y necesaria.

Pruébalo en línea .

-l hace 2 cosas:

  • habilitar la biblioteca "matemática", incluso c()para cos (x)
  • establece la precisión (escala) en 20 decimales ( bctiene un cálculo de precisión arbitrario)

No tengo muy claro el requisito de precisión. Tal como están las cosas, este programa calcula hasta 20 decimales. Si se requiere una precisión diferente, entonces scale=n;debe insertarse al comienzo del programa, donde nestá el número de lugares decimales. No sé si debo agregar esto a mi puntaje o no.

Tenga en cuenta también que para algunos números de decimales (por ejemplo, 21, pero no 20), el cálculo oscila a ambos lados de la solución en el último dígito. Por lo tanto, en la comparación de las iteraciones actuales y anteriores, divido ambos lados entre 10 ( A) para borrar el último dígito.


3

Mathematica, 22 bytes

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

entrada

[100]

salida

0.73908513321516064165531208767387340401341175890075746496568063577328 \ 46548835475945993761069317665318


2

R (+ Rmpfr), 55 bytes

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

Dennis ahora ha agregado Rmpfr a TIO para que esto funcione; Se agregaron algunos casos de prueba.

Explicación:

Toma el código que escribí de este desafío para evaluar los cos ntiempos a partir de 1, pero primero especifico la precisión en la que quiero que estén los valores creando un objeto bde clase mpfrcon valor 1y precisión n,n>=2 , por lo que obtener una mayor precisión a medida que avanzamos.

Pruébalo en línea!


3
Inténtalo de nuevo. :) En el futuro, si algo falta en TIO, no dude en dejar un mensaje en talk.tryitonline.net .
Dennis

@ Dennis Gracias! Lo tendré en cuenta en el futuro!
Giuseppe




0

Python - 89 bytes

Utiliza el módulo decimal.

from decimal import*
import math
lambda n:reduce(lambda a,b:Decimal(math.cos(a)),[1]*n,1)

84 bytes combinando importaciones.
Arnold Palmer

0

Perl 5, 41 Bytes

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

Se requiere Bignum para la precisión arbitraria. Define una función f que aplica el coseno recursivamente a 0 N veces.

TIO no parece tener bignum, así que no hay enlace :(


0

Mathematica 44 Bytes

FindRoot[Cos@x-x,{x,0},WorkingPrecision->#]&

FindRoot usa el método de Newton por defecto.


0

Python 2, 86 bytes

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

Nueva versión con la punta provista.

Python 2, 105 bytes

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

Utiliza el método de Newton y la función recursiva para calcular el valor. xes el valor inicial y nes el límite de recursividad.


El tipo de flotador incorporado de Python tiene una precisión indefinida, por lo tanto, su función no es realmente asintótica.
Post Rock Garf Hunter

Gracias, es bueno saberlo. Arreglado, supongo, ya no es muy corto :)
SydB

La sugerencia proporcionada en la pregunta probablemente sería más corta que el método de Newton.
Post Rock Garf Hunter

Gracias de nuevo, parece que me dejé llevar por las matemáticas sofisticadas.
SydB

0

Axioma, 174 bytes

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)

no golfista y comentado

-- 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

resultados:

(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

Usaría el método de Newton porque sería más rápido que el 'método cos (x) repetido'

 800   92x
1000  153x
2000  379x

donde en la primera columna está el número de dígitos y en la segunda columna, cuánto es el método de Newton más rápido que el método repetido cos (x), aquí. Buenos días

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.