Approssimazione del numero Dottie


13

Il numero di Dottie è il punto fisso della funzione coseno o la soluzione dell'equazione cos (x) = x . 1

Il tuo compito sarà creare un codice che approssima questa costante. Il codice dovrebbe rappresentare una funzione che accetta un numero intero come input e genera un numero reale. Il limite della tua funzione man mano che l'input cresce dovrebbe essere il numero di Dottie.

È possibile produrre come una frazione, un decimale o una rappresentazione algebrica di un numero. Il tuo output dovrebbe essere in grado di essere arbitrariamente preciso, float e doppi non sono sufficienti per questa sfida. Se la tua lingua non è in grado di numeri di precisione arbitrari, devi implementarli o scegliere una nuova lingua.

Questa è una domanda di quindi le risposte verranno classificate in byte, con un numero inferiore di byte migliori.

Suggerimenti

Un modo per calcolare la costante è prendere qualsiasi numero e applicare ripetutamente il coseno ad esso. Poiché il numero di applicazioni tende all'infinito, il risultato tende al punto fisso del coseno.

Ecco un'approssimazione abbastanza accurata del numero.

0.739085133215161

1: Qui prenderemo il coseno in radianti


Quindi, se stiamo usando Python, dobbiamo implementare il nostro tipo o importare Decimal?
Mr. Xcoder,

Quanto devono essere accurati i nostri invii?
Mr. Xcoder,

Va al tutorial di Jelly per rubare si ÆẠȷ¡accorge che non è valido. Tries Brachylog; oh no Brachylog non fa nemmeno galleggianti.
Erik the Outgolfer

@ Mr.Xcoder Devono essere solo asintoticamente precisi.
Post Rock Garf Hunter,

1
Mi piacerebbe vederlo in Haskell, APL e un po 'di sapore di Lisp.
Marco C

Risposte:


6

MATL , 34 30 19 byte

11 byte di sconto grazie a Sanchises !

48i:"'cos('wh41hGY$

Le ultime cifre decimali nell'output potrebbero essere disattivate. Tuttavia, il numero di cifre corrette a partire da sinistra aumenta con l'input e il risultato converge alla costante effettiva.

Provalo online!

Spiegazione

Per l'ingresso n e a partire da x = 1, questo applica la funzione

              x ↦ cos ( x )

con n -digita aritmetica a precisione variabile n volte.

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

Perché non applicarlo n volte con precisione a n cifre? Questo sembra eccessivamente complicato.
Sanchises,

Questo è incredibile. Voglio vederlo in APL.
Marco C



3

GNU bc -l, 30

Il punteggio include +1 per la -lbandiera a bc.

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

La nuova riga finale è significativa e necessaria.

Provalo online .

-l fa 2 cose:

  • abilita la libreria "matematica", incluso c()per cos (x)
  • imposta la precisione (scala) su 20 cifre decimali ( bcha un calcolo di precisione arbitrario)

Non sono molto chiaro sui requisiti di precisione. Così com'è, questo programma calcola con 20 cifre decimali. Se è richiesta una precisione diversa, è necessario scale=n;inserirla all'inizio del programma, dove si ntrova il numero di cifre decimali. Non so se dovrei aggiungere questo al mio punteggio o no.

Si noti inoltre che per alcuni numeri di cifre decimali (ad es. 21, ma non 20), il calcolo oscilla su entrambi i lati della soluzione nell'ultima cifra. Pertanto, nel confronto delle iterazioni attuali e precedenti, divido entrambi i lati per 10 ( A) per cancellare l'ultima cifra.


3

Mathematica, 22 byte

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

ingresso

[100]

produzione

0.73908513321516064165531208767387340401341175890075746496568063577328 \ 46548835475945993761069317665318


2

R (+ Rmpfr), 55 byte

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

Dennis ha ora aggiunto Rmpfr a TIO in modo che funzioni; aggiunti alcuni casi di test.

Spiegazione:

Prende il codice che ho scritto da questa sfida per valutare i cos ntempi a partire da 1, ma prima specifica la precisione in cui voglio che siano i valori creando un oggetto bdi classe mpfrcon valore1 e precisione n, n>=2, in modo da ottenere una maggiore precisione come andiamo avanti.

Provalo online!


3
Riprova. :) In futuro, se manca qualcosa a TIO, non esitare a lasciare un messaggio in talk.tryitonline.net .
Dennis,

@Dennis Grazie! Lo terrò a mente in futuro!
Giuseppe,



1

K: 6 byte

  _cos/1
0.7390851

f/si applica ffino a quando non raggiunge un punto fisso.


0

Python - 89 byte

Utilizza il modulo decimale.

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

84 byte combinando le importazioni.
Arnold Palmer,

0

Perl 5, 41 byte

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

Bignum è richiesto per la precisione arbitraria. Definisce una funzione f che applica ricorsivamente il coseno a 0 N volte.

TIO non sembra avere bignum quindi nessun link :(


0

Mathematica 44 byte

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

FindRoot utilizza il metodo di Newton per impostazione predefinita.


0

Python 2, 86 byte

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

Nuova versione utilizzando il suggerimento fornito.

Python 2, 105 byte

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

Utilizza il metodo di Newton e la funzione ricorsiva per calcolare il valore. xè il valore iniziale ed nè il limite di ricorsione.


Il tipo float incorporato di Python ha una precisione indefinita, quindi la tua funzione non è in realtà asintotica.
Post Rock Garf Hunter,

Grazie, buono a sapersi. Risolto il
problema

Il suggerimento fornito nella domanda sarebbe probabilmente più breve del metodo di Newton.
Post Rock Garf Hunter,

Grazie ancora, sembra che fossi troppo portato via con una matematica elaborata.
SydB,

0

Assioma, 174 byte

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)

non golfato e commentato

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

i risultati:

(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

Vorrei usare il metodo Newton perché sarebbe più veloce del "metodo cos (x) ripetuto"

 800   92x
1000  153x
2000  379x

dove nella prima colonna c'è il numero di cifre e nella seconda colonna c'è quanto il metodo Newton è più veloce dell'uso del metodo cos (x) ripetuto, qui. Buongiorno

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.