Przybliż numer Dottie

17

Liczba Dottiego jest stałym punktem funkcji cosinus lub rozwiązaniem równania cos (x) = x . 1

Twoim zadaniem będzie stworzenie kodu zbliżonego do tej stałej. Twój kod powinien reprezentować funkcję, która przyjmuje liczbę całkowitą jako dane wejściowe i generuje liczbę rzeczywistą. Granicą twojej funkcji wraz ze wzrostem wartości wejściowej powinna być liczba Dottie.

Możesz generować jako ułamek, dziesiętną lub algebraiczną reprezentację liczby. Twój wynik powinien być w stanie być dowolnie precyzyjny, liczba zmiennoprzecinkowa i liczba podwójna nie są wystarczające do tego wyzwania. Jeśli twój język nie jest w stanie podać dowolnych liczb dokładności, musisz je zaimplementować lub wybrać nowy język.

To jest pytanie w więc odpowiedzi będą oceniane w bajtach, przy czym mniej bajtów będzie lepszych.

Porady

Jednym ze sposobów obliczania stałej jest pobranie dowolnej liczby i wielokrotne zastosowanie do niej cosinusa. Ponieważ liczba aplikacji zmierza w kierunku nieskończoności, wynik zmierza w kierunku stałego punktu cosinusa.

Oto dość dokładne przybliżenie liczby.

0.739085133215161

1: Tutaj weźmiemy cosinus w radianach

Ad Hoc Garf Hunter
źródło
Więc jeśli używamy Pythona, musimy zaimplementować własny typ lub zaimportować Decimal?
Pan Xcoder,
Jak dokładne muszą być nasze zgłoszenia?
Pan Xcoder,
Idzie do samouczka Jelly, aby ukraść, i ÆẠȷ¡zdaje sobie sprawę, że jest nieprawidłowy. Próbuje Brachylog; o nie, Brachylog nawet nie robi spławików.
Erik the Outgolfer
1
Wydaje mi się, że wymóg „arbitralnie precyzyjny” jest nieco zbyt rygorystyczny. Dlaczego nie uznać raz poprawnej odpowiedzi x=cos(x)?
kamoroso94
2
Chciałbym to zobaczyć w Haskell, APL i trochę smaku Lisp.
Mark C

Odpowiedzi:

7

MATL , 34 30 19 bajtów

11 bajtów mniej dzięki Sanchises !

48i:"'cos('wh41hGY$

Ostatnie cyfry dziesiętne na wyjściu mogą być wyłączone. Jednak liczba poprawnych cyfr, zaczynając od lewej, zwiększa się wraz z danymi wejściowymi, a wynik jest zbieżny z rzeczywistą stałą.

Wypróbuj online!

Wyjaśnienie

Dla wejścia n i rozpoczynającego się od x = 1, dotyczy to funkcji

              x ↦ cos ( x )

z n- cyfrową arytmetyką o zmiennej precyzji n razy.

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
Luis Mendo
źródło
Dlaczego nie zastosować go n razy z dokładnością do n cyfr? To wydaje się zbyt skomplikowane.
Sanchises
1
To jest niesamowite. Chcę to zobaczyć w APL.
Mark C
4

GNU bc -l, 30

Wynik obejmuje +1 dla -lflagi do bc.

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

Ostateczna nowa linia jest znacząca i konieczna.

Wypróbuj online .

-l robi 2 rzeczy:

  • włącz bibliotekę „matematyczną”, w tym c()dla cos (x)
  • ustawia precyzję (skalę) na 20 miejsc po przecinku ( bcma dowolne obliczenia precyzji)

Nie jestem do końca pewien wymagań dotyczących precyzji. W tej chwili program oblicza do 20 miejsc po przecinku. Jeśli wymagana jest inna precyzja, scale=n;należy ją wstawić na początku programu, gdzie njest liczba miejsc dziesiętnych. Nie wiem, czy powinienem dodać to do mojego wyniku, czy nie.

Należy również zauważyć, że w przypadku niektórych miejsc po przecinku (np. 21, ale nie 20) obliczenia oscylują po obu stronach rozwiązania w ostatniej cyfrze. Tak więc w porównaniu bieżącej i poprzedniej iteracji dzielę obie strony przez 10 ( A), aby usunąć ostatnią cyfrę.

Cyfrowa trauma
źródło
3

PHP , 50 bajtów

$a=$argv[1];$i=$j=0;while($i<$a){$j=cos($j);$i++;}

Wypróbuj online!

Alex Neises
źródło
Witamy na stronie! :)
James
Uważam, że for($a=$argv[1];$a--;)$j=cos($j);echo$j;(40 bajtów) wystarczy.
Ismael Miguel,
3

K: 6 bajtów

  _cos/1
0.7390851

f/obowiązuje, fdopóki nie osiągnie ustalonego punktu.

Tangentstorm
źródło
jaka to wersja k? _to podłoga w większości znanych mi wersji. w k4 i ok można uzyskać 5 bajtów za pomocącos/1
bazgroły
K3 Wbudowane zaczynają się od podkreślenia.
tangentstorm
1
ciekawy! nie widziałem K3 na wolności. być może warto go oznaczyć jako takiego, ponieważ na tym forum jest używanych więcej niż kilka wersji :)
scrawl
2

R (+ Rmpfr), 55 bajtów

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

Dennis dodał teraz Rmpfr do TIO, więc to zadziała; dodano kilka przypadków testowych.

Wyjaśnienie:

Wykonuje kod napisałem z tym wyzwaniem , aby ocenić cos nrazy zaczynają się 1, ale najpierw określić precyzję chcę być w wartości poprzez utworzenie obiektu bklasy mpfrz wartości 1i precyzją n, n>=2tak możemy uzyskać większą precyzję jak idziemy.

Wypróbuj online!

Giuseppe
źródło
3
Spróbuj ponownie. :) W przyszłości, jeśli czegoś brakuje w TIO, nie wahaj się napisać wiadomości na talk.tryitonline.net .
Dennis
@Dennis Dziękujemy! Będę o tym pamiętać w przyszłości!
Giuseppe,
2

dzaima / APL , 55 bajtów

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

10N1NN

Brak linku do TIO, ponieważ dzaima / APL TIO nie zostało zaktualizowane do obsługi bigintegerów.

Przykład I / O:

1
9L

10
7390851332L

100
7390851332151606416553120876738734040134117589007574649656806357732846548835475945993761069317665318L

200
73908513321516064165531208767387340401341175890075746496568063577328465488354759459937610693176653184980124664398716302771490369130842031578044057462077868852490389153928943884509523480133563127677224L
dzaima
źródło
1

Mathics or Mathematica, 46 bajtów

{$MaxPrecision=#}~Block~Cos~FixedPoint~N[1,#]&

Wypróbuj online!

notjagan
źródło
1

Pyth , 57 54 bajtów

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

Byłoby to znacznie krótsze, gdybyśmy nie potrzebowali Decimal, aby był zgodny ze specyfikacją, ale tak właśnie jest.

Edytuj 1: -3 bajty, ponieważ i tak potrzebujemy liczby, więc możemy użyć Xzwróconej kopii globals()długości jako naszej wartości początkowej, przenosząc ją do końca i usuwając a $oraz trochę białych znaków.

Wypróbuj online!

znani1622
źródło
1

APL (Dyalog Unicode) , 9 bajtów

2○⍣=1

Wypróbuj online!

( Uwaga: TIO ma dodatkowy ⎕←; jest to wymagane przez TIO. „Autonomiczny” interpreter APL użyłby dokładnego wyrażenia pokazanego powyżej. Podana liczba bajtów jest tym, co TIO oblicza dla powyższego wyrażenia, a nie dla tego z ⎕←. )

Rozkład / objaśnienie:

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.

Przy pierwszym obliczeniu funkcji cos x (2 ○ x), przy x = 1, nie będą one równe. cos 1 wynosi 0,5403 ..., więc dokonaj ponownej oceny, zastępując 1 wartością 0,5403 ... i powtarzaj proces, aż (2 ○ x) = x, co występuje dla x = 0,73908 ...

Tworząc to, użyłem domyślnej wartości dla „precyzji drukowania”, którą można ustawić w APL za pomocą ⎕PP ←; maksymalna wartość ⎕PP dozwolona przez Dyalog APL to 34 cyfry.

Ponadto domyślną precyzją dla tej implementacji są liczby zmiennoprzecinkowe 64-bitowe; można użyć 128-bitowych liczb zmiennoprzecinkowych, ustawiając ⎕FR ← 1287. Obliczanie TIO odbywa się przy użyciu 64-bitowych liczb zmiennoprzecinkowych.

Żadna faktyczna implementacja języka komputerowego nie może dać prawdziwie arbitralnej precyzji; Jednak kod dla teoretycznego APL że nie realizować dowolną precyzję byłby dokładnie taki sam .

Jeff Zeitlin
źródło
To jest 5 bajtów.
Adám
Jak wspomniano na czacie, powinno to być rozwiązanie NARS2000, w Dyalog jest nieprawidłowe. Następnie, aby uczynić go poprawnym wpisem, powinieneś ustawić ⎕CT←0i prawdopodobnie przypisać dane wejściowe do ⎕FPC.
dzaima
To nie obsługuje arbitralnej precyzji, która jest wymagana przez specyfikację:Your output should be capable of being arbitrarily precise, floats and doubles are not sufficient for this challenge.
Grimmy
@ Adám Ta odpowiedź jest nieprawidłowa; patrz komentarz Grimmy powyżej. Rozwiązanie dzaima działałoby, ale nie jest to pierwsze.
SS Anne
0

Python - 89 bajtów

Wykorzystuje moduł dziesiętny.

from decimal import*
import math
lambda n:reduce(lambda a,b:Decimal(math.cos(a)),[1]*n,1)
Maltysen
źródło
84 bajty poprzez połączenie importów.
Arnold Palmer,
72 bajty
Maria Miller
0

Perl 5, 41 bajtów

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

Bignum jest wymagane dla dowolnej precyzji. Definiuje funkcję f, która rekurencyjnie stosuje cosinus do 0 N razy.

Wydaje się, że TIO nie ma bignum, więc nie ma linku :(

theLambGoat
źródło
0

Mathematica 44 bajtów

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

FindRoot domyślnie używa metody Newtona.

Kelly Lowder
źródło
0

Python 2, 86 bajtów

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

Nowa wersja za pomocą dostarczonej końcówki.

Python 2, 105 bajtów

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

Wykorzystuje metodę Newtona i funkcję rekurencyjną do obliczania wartości. xjest wartością początkową i nstanowi limit rekurencji.

SydB
źródło
Wbudowany typ pływaka w Pythonie ma nieokreśloną precyzję, więc twoja funkcja nie jest w rzeczywistości asymptotyczna.
Ad Hoc Garf Hunter
Dzięki, dobrze wiedzieć. Naprawdę, chyba nie bardzo krótko :)
SydB
Wskazówka zawarta w pytaniu byłaby prawdopodobnie krótsza niż metoda Newtona.
Ad Hoc Garf Hunter
Jeszcze raz dziękuję, wygląda na to, że zbyt pochłonęła mnie fantazyjna matematyka.
SydB,
Twoja funkcja powinna przyjmować tylko 1 argument nzgodnie z wymaganiami, więc musisz ustawić domyślnie x=0. Również ta funkcja nie jest arbitralnie precyzyjna, ponieważ math.cosjest to stała precyzja.
Surculose Plwocina
0

Aksjomat, 174 bajty

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)

nie golfił i komentował

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

wyniki:

(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

Użyłbym metody Newtona, ponieważ byłaby szybsza niż „metoda powtórzonych cos (x)”

 800   92x
1000  153x
2000  379x

gdzie w pierwszej kolumnie jest liczba cyfr, a w drugiej kolumnie jest o ile metoda Newtona jest szybsza niż w przypadku powtarzanej metody cos (x), tutaj. Dzień dobry

RosLuP
źródło
0

Stax , 5 bajtów

╘ñ[EΩ

Uruchom i debuguj Wyjaśnienie:

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
Joe
źródło
1
To nie obsługuje arbitralnej precyzji, która jest wymagana przez specyfikację:Your output should be capable of being arbitrarily precise, floats and doubles are not sufficient for this challenge.
Grimmy
0

JavaScript (Node.js) , 84 bajtów

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)

Wypróbuj online!

Ma dokładność z grubsza n-1cyfr. BigInt jest używany i cos(x)jest obliczany na podstawie jego rozszerzenia Taylora. Ta I-Z>>2nczęść jest używana tylko w celu uniknięcia zapętlenia na zawsze (z kosztem 4 bajtów i pewną precyzją). Chociaż teoretycznie ma zastosowanie do dowolnej precyzji, praktyczny zasięg n<63wynika z przepełnienia stosu.

Krótszy (82 bajty), nie martw się przepełnieniem stosu, ale znacznie mniej precyzji

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

Znacznie krótszy (80 bajtów), większy zakres aż do przepełnienia stosu ( n<172), ale taka sama precyzja jak 82 bajty.

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)

Jeśli arbitralna precyzja nie jest głównym punktem, to 25 bajtów:

F=n=>n?Math.cos(F(n-1)):1
Shieru Asakoto
źródło