Орієнтовна цифра Dottie


17

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

Вашим завданням буде зробити код, який наближає цю константу. Ваш код повинен представляти функцію, яка приймає ціле число як вхід і виводить дійсне число. Обмеженням вашої функції в міру зростання введення повинно бути число Dottie.

Ви можете виводити у вигляді дробу, десяткових чи алгебраїчних зображень числа. Ваш вихід повинен бути здатний бути довільно точним, поплавці та дублі недостатньо для цього завдання. Якщо ваша мова не здатна до довільних точних чисел, ви повинні або їх реалізувати, або вибрати нову мову.

Це питання з тому відповіді будуть набиратись у байтах, менша кількість байтів - краща.

Поради

Один із способів обчислення константи - це взяти будь-яке число і багаторазово застосувати до нього косинус. Оскільки кількість застосувань тяжіє до нескінченності, результат прагне до фіксованої точки косинуса.

Ось досить точне наближення числа.

0.739085133215161

1: Тут ми візьмемо косинус у радіанах


Отже, якщо ми використовуємо Python, ми повинні реалізувати власний тип чи імпортувати Decimal?
Містер Xcoder

Наскільки точні повинні бути наші матеріали?
Містер Xcoder

Іде до підручника Jelly, щоб викрасти, ÆẠȷ¡розуміє, що це недійсно. Пробує Брахілог; о, ні Брахілог навіть не плаває.
Erik the Outgolfer

1
Я відчуваю, що вимога "довільно точної" трохи надто сувора. Чому б не вважати відповідь одночасно дійсною x=cos(x)?
kamoroso94

2
Я хотів би бачити це в Haskell, APL та деяких смаках Lisp.
Марк C

Відповіді:


8

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

1
Чому б просто не застосувати його n разів з точністю до n цифр? Це здається надмірно складним.
Санчіз

1
Це неймовірно. Я хочу бачити це в APL.
Марк C


5

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), щоб стерти останню цифру.



4

dzaima / APL , 55 байт

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

10N1NN

Немає посилання на TIO, оскільки dzaima / APL TIO не було оновлено для підтримки великих інтегралів.

Приклад вводу / виводу:

1
9L

10
7390851332L

100
7390851332151606416553120876738734040134117589007574649656806357732846548835475945993761069317665318L

200
73908513321516064165531208767387340401341175890075746496568063577328465488354759459937610693176653184980124664398716302771490369130842031578044057462077868852490389153928943884509523480133563127677224L

3

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 .
Денніс

@Dennis Дякую! Я буду мати це на увазі в майбутньому!
Джузеппе


3

К: 6 байт

  _cos/1
0.7390851

f/застосовується fдо досягнення фіксованої точки.


яка версія k це? _це підлога у більшості варіантів, які я знаю. в k4 та oK ви можете отримати 5 байт зcos/1
scrawl

К3. Вбудовані модулі починаються з підкреслення.
дотична буря

2
цікаво! я не бачив k3 в дикій природі. можливо, варто маркувати його як таке, оскільки на цьому форумі використовується більше декількох версій :)
scrawl

Якщо рішення програми Dyalog APL вважається недійсним, це слід вважати недійсним, так як це точно той же алгоритм.
Джефф Зейтлін



2

Pyth , 57 54 байти

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

Це було б набагато коротше, якби нам не знадобився Десятковий, щоб бути спец., Але це є.

Відредагуйте 1: -3 байти, оскільки нам все одно потрібне число, тому ми можемо використовувати Xповернуту копію globals()довжини в якості вихідного значення, перемістивши її до кінця та видаливши $пробіл та деякий пробіл.

Спробуйте в Інтернеті!


2

APL (Dyalog Unicode) , 9 байт

2○⍣=1

Спробуйте в Інтернеті!

( Примітка. У TIO є додаткове ⎕←; цього вимагає TIO. "Автономний" інтерпретатор APL використовує точний вираз, показаний вище. Дане число байтів - це те, що TIO обчислює для виразу, наведеного вище, а не для того, з яким ⎕←. )

Розкладання / пояснення:

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.

Перший раз, коли оцінюється функція cos x (2 ○ x), при цьому х = 1, вони не будуть рівними. cos 1 дорівнює 0,5403 ..., тому переоцініть, замінивши 1 на 0,5403 ... і повторіть процес до тих пір, поки (2 ○ x) = x, що відбувається при x = 0,73908 ...

Створюючи це, я використав значення за замовчуванням для "точності друку", яке можна встановити в APL за допомогою ⎕PP ←; максимальне значення для ⎕PP, яке дозволяє Dyalog APL, - 34 цифри.

Крім того, точність за замовчуванням для цієї реалізації - це 64-бітні плавки; можна використовувати 128-бітні поплавці, встановивши ⎕FR ← 1287. Розрахунок TIO проводиться з 64-бітовими поплавцями.

Жодна реальна реалізація комп'ютерної мови не може дати справді довільну точність; Однак код для теоретичного APL , що було реалізувати довільну точність була б точно такою ж .


Це 5 байт.
Адам

Як ви згадували в чаті, це має бути рішенням NARS2000, воно недійсне в Dyalog. Потім, щоб зробити це правильним записом, слід встановити ⎕CT←0і, ймовірно, призначити вхід ⎕FPC.
dzaima

1
Це не підтримує довільної точності, якої вимагає специфікація:Your output should be capable of being arbitrarily precise, floats and doubles are not sufficient for this challenge.
Grimmy

1
@ Adám Ця відповідь недійсна; дивіться коментар Grimmy вище. Рішення dzaima працює, але це не перше.
СС Енн

1
@JeffZeitlin ваша відповідь все ще недійсна. Додавання (очевидно неправильного) зауваження про те, як довільна точність неможлива, не допомагає. Спробуйте ознайомитися з деякими правильними відповідями для порівняння.
Grimmy

2

JavaScript (Node.js) , 84 байти

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)

Спробуйте в Інтернеті!

Має точність приблизно в n-1цифрах. BigInt використовується і cos(x)розраховується з використанням його розширення Тейлора. I-Z>>2nЧастина використовується тільки для запобігання зациклення (з вартістю 4 байта і деякою точністю). Хоча теоретично застосовано для довільної точності, практичний діапазон n<63пояснюється переповненням стека.

Коротше (82 байти), не турбує переповнення стека, але набагато менша точність

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

Набагато коротший (80 байт), більший діапазон до переповнення стека ( n<172), але така ж точність, як і 82-байт.

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)

Якщо довільна точність не є головним моментом, то 25 байт:

F=n=>n?Math.cos(F(n-1)):1


1

Perl 5, 41 байт

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

Бігнум необхідний для довільної точності. Визначає функцію f, яка рекурсивно застосовує косинус до 0 N разів.

TIO, схоже, не має bignum, тому немає посилання :(


1

Математика 44 байти

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

FindRoot використовує метод Ньютона за замовчуванням.


1

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 має невизначену точність, тому ваша функція насправді не є асимптотичною.
Ad Hoc Garf Hunter

Дякую, добре знати. Виправлено, мабуть, уже не дуже короткий
тхо

Порада, надана у питанні, ймовірно, буде коротшою, ніж метод Ньютона.
Ad Hoc Garf Hunter

Ще раз дякую, схоже, я занадто захопився фантазійною математикою.
SydB

Ваша функція повинна приймати лише 1 аргумент nвідповідно до вимоги, тому вам потрібно за замовчуванням x=0. Також ця функція не є довільною точністю, оскільки math.cosє фіксованою точністю.
Surculose Sputum

1

Аксіома, 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). Добрий ранок


0

Стакс , 5 байт

╘ñ[EΩ

Запустити та налагодити це Пояснення:

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

2
Це не підтримує довільної точності, якої вимагає специфікація:Your output should be capable of being arbitrarily precise, floats and doubles are not sufficient for this challenge.
Grimmy
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.