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


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

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




3

K: 6 bajtów

  _cos/1
0.7390851

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


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!


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


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!


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 .


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

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


0

Mathematica 44 bajtów

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

FindRoot domyślnie używa metody Newtona.


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.


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


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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.