Aproximado do número Dottie


13

O número de Dottie é o ponto fixo da função cosseno ou a solução da equação cos (x) = x . 1

Sua tarefa será criar código que se aproxime dessa constante. Seu código deve representar uma função que recebe um número inteiro como entrada e gera um número real. O limite da sua função à medida que a entrada aumenta deve ser o número Dottie.

Você pode imprimir como uma fração, um decimal ou uma representação algébrica de um número. Sua saída deve ser arbitrariamente precisa, flutuações e duplas não são suficientes para esse desafio. Se seu idioma não for capaz de números de precisão arbitrários, você deverá implementá-los ou escolher um novo idioma.

Esta é uma questão de para que as respostas sejam pontuadas em bytes, com menos bytes sendo melhores.

Dicas

Uma maneira de calcular a constante é pegar qualquer número e aplicar repetidamente o cosseno. Como o número de aplicações tende ao infinito, o resultado tende ao ponto fixo do cosseno.

Aqui está uma aproximação bastante precisa do número.

0.739085133215161

1: Aqui pegaremos cosseno em radianos


Então, se estivermos usando Python, devemos implementar nosso próprio tipo ou importação Decimal?
Xcoder

Qual a precisão das nossas submissões?
Sr. Xcoder

Vai ao tutorial da Jelly para roubar e ÆẠȷ¡percebe que é inválido. Tenta Brachylog; oh não, o Brachylog nem faz carros alegóricos.
Erik the Outgolfer

@ Mr.Xcoder Eles só devem ser assintoticamente precisos.
Post Rock Garf Hunter

1
Eu gostaria de ver isso em Haskell, APL e algum sabor de Lisp.
Mark C

Respostas:


6

MATL , 34 30 19 bytes

11 bytes de desconto graças à Sanchises !

48i:"'cos('wh41hGY$

Os últimos números decimais na saída podem estar desativados. No entanto, o número de figuras corretas começando da esquerda aumenta com a entrada e o resultado converge para a constante real.

Experimente online!

Explicação

Para a entrada n , e começando em x = 1, isso aplica a função

              x ↦ cos ( x )

com n- dígitos de precisão variável aritmética n vezes.

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 que não aplicá-lo n vezes com precisão de n dígitos? Isso parece muito complicado.
Sanchises

Isto é incrível. Eu quero vê-lo no APL.
Mark C



3

GNU bc -l, 30

A pontuação inclui +1 para -lsinalizar para bc.

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

A nova linha final é significativa e necessária.

Experimente online .

-l faz 2 coisas:

  • ative a biblioteca "math", incluindo c() para cos (x)
  • define precisão (escala) para 20 casas decimais ( bcpossui cálculo de precisão arbitrário)

Não sou muito claro sobre o requisito de precisão. Como é, este programa calcula até 20 casas decimais. Se uma precisão diferente for necessária, ela scale=n;precisará ser inserida no início do programa, onden é o número de casas decimais. Não sei se devo adicionar isso à minha pontuação ou não.

Observe também que, para alguns números de casas decimais (por exemplo, 21, mas não 20), o cálculo oscila em ambos os lados da solução no último dígito. Assim, na comparação das iterações atuais e anteriores, divido os dois lados por 10 ( A) para apagar o último dígito.


3

Mathematica, 22 bytes

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

entrada

[100]

resultado

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 agora adicionou Rmpfr ao TIO, para que isso funcione; adicionou alguns casos de teste.

Explicação:

Toma o código que escreveu a partir deste desafio para avaliar cos nvezes a partir de 1, mas primeiro eu especificar a precisão Quero que os valores para a criando um objeto bda classe mpfrcom o valor 1e precisão n, n>=2, então temos mais precisão à medida que avançamos.

Experimente online!


3
Tente novamente. :) No futuro, se algo estiver faltando no TIO, não hesite em deixar uma mensagem no talk.tryitonline.net .
Dennis

@ Dennis Obrigado! Vou manter isso em mente no futuro!
Giuseppe




0

Python - 89 bytes

Usa o módulo decimal.

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

84 bytes combinando importações.
Arnold Palmer

0

Perl 5, 41 bytes

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

Bignum é necessário para a precisão arbitrária. Define uma função f que aplica recursivamente cosseno a 0 N vezes.

O TIO não parece ter bignum, então não há link :(


0

Mathematica 44 Bytes

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

FindRoot usa o método de Newton por padrão.


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

Nova versão usando a dica fornecida.

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

Usa o método de Newton e a função recursiva para calcular o valor. xé o valor inicial e né o limite de recursão.


O tipo de flutuador interno do Python tem precisão indefinida, portanto, sua função não é realmente assintótica.
Post Rock Garf Hunter

Obrigado, bom saber. Corrigido eu acho, não muito curto mais tho :)
SydB

A dica fornecida na pergunta provavelmente seria mais curta que o método de Newton.
Post Rock Garf Hunter

Mais uma vez obrigado, parece que eu estava muito empolgado com a matemática sofisticada.
SydB 04/08/19

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)

ungolfed e comentou

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

Eu usaria o método Newton porque seria mais rápido que o 'método cos (x) repetido'

 800   92x
1000  153x
2000  379x

onde na primeira coluna há o número de dígitos e na segunda coluna há quanto método de Newton é mais rápido do que o método repetido de cos (x), aqui. Bom Dia

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.