Приблизительное число Дотти


13

Число Дотти является фиксированной точкой косинус-функции или решением уравнения cos (x) = x . 1

Ваша задача будет сделать код, который приближает эту константу. Ваш код должен представлять функцию, которая принимает целое число в качестве входных данных и выводит действительное число. Пределом вашей функции при увеличении входных данных должно быть число Дотти.

Вы можете вывести в виде дроби, десятичного или алгебраического представления числа. Ваш вывод должен быть сколь угодно точным, поплавков и двойников недостаточно для этой задачи. Если ваш язык не способен использовать числа произвольной точности, вы должны либо реализовать их, либо выбрать новый язык.

Это вопрос по поэтому ответы будут оцениваться в байтах, при этом меньшее количество байтов будет лучше.

подсказки

Один из способов вычисления константы состоит в том, чтобы взять любое число и повторно применить к нему косинус. Поскольку число приложений стремится к бесконечности, результат стремится к фиксированной точке косинуса.

Вот довольно точное приближение числа.

0.739085133215161

1: Здесь мы будем принимать косинус в радианах


Итак, если мы используем Python, мы должны реализовать наш собственный тип или импорт Decimal?
Мистер Кскодер,

Насколько точными должны быть наши материалы?
г-н Xcoder

Идет в учебник Jelly, чтобы украсть, ÆẠȷ¡понимает, что это недействительно. Пытается брахилог; о, нет, брахилог даже не плавает.
Эрик Outgolfer

@ Mr.Xcoder Они должны быть только асимптотически точными.
Сообщение Рок Гарф Хантер

1
Я хотел бы видеть это в Haskell, APL и некотором аромате Lisp.
Марк С

Ответы:


6

MATL , 34 30 19 байтов

11 байт благодаря Sanchises !

48i:"'cos('wh41hGY$

Последние десятичные цифры в выходных данных могут быть отключены. Тем не менее, количество правильных цифр, начиная с левой, увеличивается с вводом, и результат сходится к фактической константе.

Попробуйте онлайн!

объяснение

Для входа n , начиная с x = 1, применяется функция

              x ↦ cos ( x )

с n -значной арифметикой переменной точности n раз.

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

Почему бы просто не применить его n раз с точностью до n цифр? Это кажется слишком сложным.
Санчиз

Это невероятно. Я хочу видеть это в APL.
Марк С



3

GNU bc -l, 30

Оценка включает +1 для -lфлага bc.

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

Последний перевод строки важен и необходим.

Попробуйте онлайн .

-l делает 2 вещи:

  • включить библиотеку "математика", в том числе c()для cos (x)
  • устанавливает точность (масштаб) до 20 знаков после запятой ( bcимеет произвольный расчет точности)

Я не совсем понимаю требования к точности. Как есть, эта программа рассчитывает до 20 знаков после запятой. Если требуется другая точность, то ее scale=n;необходимо вставить в начале программы, где nуказано количество десятичных знаков. Я не знаю, должен ли я добавить это к моему счету или нет.

Также обратите внимание, что для некоторого числа десятичных разрядов (например, 21, но не 20), расчет колеблется с обеих сторон решения в последней цифре. Таким образом, при сравнении текущей и предыдущей итераций я делю обе стороны на 10 ( A), чтобы стереть последнюю цифру.


3

Mathematica, 22 байта

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

вход

[100]

выход

0,73908513321516064165531208767387340401341175890075746496568063577328 \ 46548835475945993761069317665318


2

R (+ Rmpfr), 55 байтов

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

Деннис теперь добавил Rmpfr в TIO, так что это будет работать; добавил несколько тестовых случаев.

Объяснение:

Принимает код, который я написал из этой задачи, для оценки cos nвремени, начиная с которого 1, но сначала я определяю точность, в которой должны быть значения, создавая объектb класса mpfrсо значением 1и точностью n, n>=2так мы получим больше точности , как мы идем вместе.

Попробуйте онлайн!


3
Попробуйте еще раз. :) В будущем, если чего-то не хватает в TIO , не стесняйтесь оставлять сообщения на talk.tryitonline.net .
Деннис

@ Денис Спасибо! Я буду помнить это в будущем!
Джузеппе



1

К: 6 байт

  _cos/1
0.7390851

f/применяется, fпока не достигнет фиксированной точки.



0

Perl 5, 41 байт

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

Bignum требуется для произвольной точности. Определяет функцию f, которая рекурсивно применяет косинус до 0 N раз.

TIO, похоже, не имеет bignum, поэтому нет ссылки :(



0

Python 2, 86 байт

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

Новая версия, используя предоставленный совет.

Python 2, 105 байт

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

Использует метод Ньютона и рекурсивную функцию для вычисления значения. xявляется начальным значением и nявляется пределом рекурсии.


Встроенный тип Python с плавающей точкой имеет неопределенную точность, поэтому ваша функция на самом деле не асимптотическая.
Сообщение Рок Гарф Хантер

Спасибо, приятно знать. Исправлено, я думаю, уже не очень коротко, хотя :)
SydB

Наконечник, представленный в вопросе, вероятно, будет короче, чем метод Ньютона.
Сообщение Рок Гарф Хантер

Еще раз спасибо, кажется, я был слишком увлечен необычной математикой.
17

0

Аксиома, 174 байта

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)

разглаженный и прокомментированный

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

Результаты:

(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

Я бы использовал метод Ньютона, потому что он был бы быстрее, чем «повторный метод cos (x)»

 800   92x
1000  153x
2000  379x

где в первом столбце указано число цифр, а во втором столбце указано, насколько метод Ньютона быстрее, чем повторный метод cos (x), здесь. Доброе утро

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.