Приблизна кількість пластику


24

Змагання

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

Для того, щоб точно вказати число для цілей цього виклику, ми будемо використовувати таке визначення (хоча є багато еквівалентних визначень, і ви можете використовувати будь-яке визначення, яке ви хочете, поки воно стосується однакового числа):

Пластичне число - це дійсне число ρ таке, що ρ ³ = ρ +1.

Ваше завдання полягає в тому, щоб написати програму або функцію, яка приймає ціле число x як вхідний (з x > 1) і виробляє наближення до ρ як вихід, таким чином, що чим більше значення x отримує, тим ближче вихід до ρ ( з максимум кінцевим числом винятків; перебування на тому ж значенні для цієї мети вважається «ближчим»), і для будь-якого додатного числа δ , у вашу програму є деякий вхід x, який дає результат, який знаходиться в межах δ з ρ .

Роз'яснення

  • Якщо ви виводите за допомогою методу, який по суті виводить рядки (наприклад, стандартний вихідний потік), ви можете відформатувати вихід або в десятковій формі (наприклад 1.3247179572), або як співвідношення двох цілих чисел із /символом між ними.
  • Якщо ви виводите як значення в межах своєї мови програмування (наприклад, повертаючись з функції), воно повинно бути фіксованої, плаваючої або раціонального типу. (Зокрема, ти не можеш використовувати типи даних, які символічно зберігають числа, якщо вони не використовуються лише для відношення двох цілих чисел. Отже, якщо ви використовуєте Mathematica або подібну мову, вам потрібно буде включити додаткові код, щоб фактично генерувати цифри виводу.)
  • Ваша відповідь повинна працювати в гіпотетичному варіанті вашої мови, в якому цілі числа можуть бути довільно великими, а пам'ять (включаючи стек) необмежена. Ви можете не припускати, що арифметика з плаваючою комою у вашій мові довільно точна, але натомість повинна використовувати її фактичну точність (мається на увазі, що виведення числа з плаваючою комою стане можливим лише мовами, де може бути точність чисел з плаваючою комою контролюється під час виконання).
  • x може мати будь-яке значення, яке ви хочете (до тих пір, поки збільшення його дає більш точні результати). Я гадаю, що більшість подань дозволить йому контролювати кількість цифр виробленого продукту або кількість ітерацій алгоритму, використовуваного вашою програмою для сходження на пластичне число, але інші значення є прийнятними.

Тестова шафа

Ось перші кілька цифр пластичного числа:

1.32471795724474602596090885

Більше цифр доступно на OEIS .

Стан перемоги

Як зазвичай для , коротше краще, вимірюється в байтах. Однак сміливо публікуйте відповіді, навіть якщо вони не виграють, якщо вони додають щось (наприклад, іншу мову чи інший алгоритм) до існуючих відповідей.


1
hmm, (cbrt (108 + 12 * sqrt (69)) + cbrt (108-12 * sqrt (69))) / 6, здається, це вдалий час для використання наближення Дрейка: sqrt (69) = 8. щось bit.ly/2rCqedX ^ _ ^
DrQuarius

2
Чи можемо ми також припустити, що глибина рекурсії / стека необмежена?
xnor

Щоб уточнити другий момент, чи можемо ми використовувати бібліотеки довільної точності (наприклад, mpmath в Python)? Вони використовують допоміжний тип даних, але чи вважаєте ви це "зберіганням речей" символічно?
Бетмен

1
Ну, принаймні, я б очікував, що відповіді сходяться до ρ . Крім того, "чесне" рішення може легко провалити тест x> y -> | ρx - ρ | > | ρy - ρ | для кінцевої кількості пар (x, y) . Якщо це не прийнятно, я думаю, що це слід зробити більш чітким у специфікації.
Денніс

6
Багато відповідачів потрапили в пастку (?) Обчислення наближення х знаків до ρ, проблема полягає в тому, що, мабуть, існує нескінченно багато x таких, що наближення (x + 1) -знака не краще, ніж наближення x знаків. Вам, мабуть, слід уточнити, чи планували ви це дозволити. Якщо цього не зробити, замініть «ближче» на «суворо ближче»; якщо ви робите, "принаймні так близько", чи щось. Ви також можете розглянути більш низьку вимогу, щоб послідовність переходила до ρ, що додатково дозволило б відповісти xnor.
Андерс Касеорг

Відповіді:


10

Python 2 , 49 байт

n=x=input()
while n**3/x/x<n+x:n+=1
print n,'/',x

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

Ідея полягає в тому, щоб висловити ρз ρ³=ρ+1у вигляді дробу n/x, знаменник якого xє параметр точності введення. Ми беремо (n/x)³=n/x+1і чіткі знаменники, щоб отримати n³=x²(x+n).

Оскільки LHS зростає nшвидше, ніж RHS, ми можемо наблизити точку рівності nяк найменшу до n³≥x²(x+n). Код підраховується, nпоки це не так, починаючи з xякого менше.

Невеликий байт - це розділити обидві сторони на записувати n³/x²≥x+n(заперечується в whileумові). Це розділення підлоги в коді, але втрачена дробова частина незначна.

Альтернативу ж довжини замість цього ставить xяк чисельник:

Python 2 , 49 байт

n=x=input()
while x**3/n/n<n+x:n-=1
print x,'/',n

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


Хоча цей вихід сходиться до ρ (∀ε> 0 ∃x₀ ∀x ≥ x₀ | f (x) - ρ | <ε), він не задовольняє „чим більше значення x отримує, тим ближче вихід до ρ (максимум з кінцевим числом винятків) ”(∃x₀ ∀x ≥ x₀ | f (x + 1) - ρ | <| f (x) - ρ |).
Андерс Касеорг

Цю проблему можна вирішити за допомогою, 2**input()а не просто input(); то кожне наближення буде не менш точним, як попереднє.

10

Математика, 20 байт

#^3-#-1&~Root~1~N~#&

Вбудована Rootфункція Mathematica дає розв'язки поліноміального рівняння f[x] == 0.

Пояснення

#^3-#-1&~Root~1~N~#&
                   &  (* Function *)
#^3-#-1&              (* A pure-function polynomial, x^3-x-1 *)
        ~Root~1       (* Find the first root *)
               ~N~#   (* approximate to (input) digits *)

Зразок вводу / виводу

In[1]:= f=#^3-#-1&~Root~1~N~#&;
        f[1]

Out[1]= 1.

In[2]:= f[9]

Out[2]= 1.32471796

In[3]:= f[100]

Out[3]= 1.324717957244746025960908854478097340734404056901733364534015050302827851245547594054699347981787280

PS: Root[x^3-x-1,1]~N~#&працює нормально (не дивлячись на те, що xце не змінюється) для одного і того ж кількості байтів.
Грег Мартін

@AndersKaseorg: Я змінив це правило, оскільки воно було чітко порушено. Невірні відповіді не були визнані недійсними, але деякі відповіді (як ця) стали дійсними.

6

Математика, 27 байт

x/.Solve[x^3==x+1>2,x]~N~#&

-1 байт від Мартіна
-2 байт від ов

вхід

[27]

вихід

{1.32471795724474602596090885}


Solve[x^3==x+1>2,x]~N~#&за 24 байти
ов

1
Результат цього {{x -> 1.32...}}хоча. Ви можете перевірити, чи це допустимий вихідний формат.
Мартін Ендер

ок .. все виправлено я здогадуюсь
J42161217

Це все ще {1.32...}насправді, але цей формат, мабуть, менш спірний.
Мартін Ендер

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

6

sed , 67 60 (59 + 1) байт

s,^,1/1/1 ,
:;s,(1*/(1*)/(1*).*)1$,\2\3/\1,
t
s,(/1*).*,\1,

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

+1 для -Eпрапора (ERE замість BRE). Вхід і вихід є однотипними: вхід 11111 для x = 5, наприклад, вихід - це частка з двох одинарних чисел: згаданий вище вхід 11111 дає вихід 11111/1111 (5/4 у десятковій кількості).

Наближає пластичне число як частку між послідовними елементами послідовності Падована .


1
FWIW вам не потрібно пробілу після bкоманди, але ви можете скоротити її ще за допомогою порожньої мітки ( :і bбез аргументу). tio.run/#%23K05N@f@/…
Йорданія

О прекрасно. І я можу зберегти ще 4 байти, використовуючи tзамість цього b, так що це досить приємне збереження. Дякую :)
FireFly

5

Математика, 27 байт

Nest[(1+#)^(1/3)&,1,#]~N~#&

Використовується усічений наближення вкладеної кубічної радикальної форми √ (1 + ³√ (1 + ³√ (1 + ...))) . Незважаючи на те, що на виході завжди буде розміщено x-1 десяткових знаків, результат насправді менш точний, ніж цей, оскільки вираз конвергується повільніше, ніж одна цифра за ітерацію ( x також використовується як кількість вкладених радикалів, які обчислюються). Наприклад x = 100 дає

_________________________________________________________________________
1.324717957244746025960908854478097340734404056901733364534015050302827850993693624204577670741656151

де правильно накреслена частина.


Я планував написати цей алгоритм dc, але отримав стимію, оскільки виявилося, що він не має кубової кореневої операції, і збільшити число до потужності ⅓ також не працює :-( Принаймні, ви завжди можете розраховувати на Математика мати відповідні вбудовані…

3
@ ais523 Насправді немає, CubeRootале ніхто не має байтів за це.
Мартін Ендер

4

Октава , 50 байт

@(n)char(digits(n)*0+vpasolve(sym('r^3-r-1'))(1));

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

Визначає анонімну функцію з nпотрібною кількістю цифр виводу.

Ця відповідь зловживає тим, що digitsповертає поточне налаштування для кількості цифр у арифметиці зі змінною точністю. Це означає, що ми можемо просто використовувати його в анонімній функції без помилок щодо "Занадто багато вихідних аргументів".

Крім цього, це справді просто: vpasolveце коротке значення для арифметичного рішення з змінною точністю, з точністю, встановленою в останньому дзвінку digits. Оскільки vpaце символ символічного типу в Octave, який заборонений за специфікацією, ми просто обертаємо всю функцію, char(...)щоб отримати вихідний рядок. Зауважте, що в solveі vpasolve, f==0мається на увазі, так r^3==r+1було замінено наr^3-r-1 (==0)


Я пішов і змінив питання, щоб воно не забороняло відповіді, як це (це не передбачалося).

@ ais523 Дякуємо за повідомлення!
Санчіз

4

MATL ( 27 28 байт)

7BG:"t@)y@Q)+h]tG3+)yG2+)/

Моє перше рішення (27 байт)

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

Це, звичайно, не оптимально, я все ще звикаю до MATL.

Пояснення:

Я створюю послідовність Padovan до введення + 3, а потім знаходжу відношення останніх двох чисел.

7B     % Turn 7 into binary to give 1 1 1 
G:"    % For k=1:input do...
t@)    % Existing sequence member k
y@1+)  % Existing sequence member k+1
+h     % Add them together and concatenate to the sequence array
]      % End loop
tG3+)  % Final sequence member
yG2+)  % Second last sequence member
/      % Divide to approximate ρ

Належний вихід фракції (35 байт) (28 байт, @Sanchises):

Однак перше рішення не задовольняє потреби в довільній точності, що є межею плаваючої точки за замовчуванням MATL. Тому замість додавання декількох байтів, щоб розширити цю точність, простіше взяти правильний шлях дробу та записати дріб кінцевих двох цілих чисел у (N-1) -му та N- му елементах усіченої послідовності Падована.

наприклад, "114/86"

7BG: "t @) y @ 1 +) + h] tG3 +) V '/' YcyG2 +) VYc

7BG:"t@tQh)sh]tJ)V47hyJq)Vh&

Надано користувачем @Sanchises. :)

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

Неітераційна оцінка:

Зокрема, мій найкоротший код для "точної" версії - (23 байти):

1-1h69X^12**108+1I/^6/s

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

... але не дає довільної точності. Цікаво, чи може хтось скорегувати це, щоб виконати правила (використовувати введення тощо) і все-таки додати менше 5 байт? : P


1
1+можна скоротити до Q. Зважаючи на це, ви можете замінити @)y@1+)+на справедливі @tQh)s. Крім того, ви можете використовувати Jдля позначення кінця масиву; і нарешті, MATL не розрізняє нормальні масиви та символьні масиви, тому ви можете замінити Ycїх h(вам не потрібна додаткова функціональність Yc). Це дає лише 28 байт: 7BG:"t@tQh)sh]tJ)V47hyJq)Vh&(зауважте, &щоб запобігти зайвий вихід і замінити '/'на 47).
Санчіз

1
Kudos для 7Bхоч, набагато краще, ніж наївно штовхаєlllv
Sanchises

1
@DrQuarius Останню версію завжди можна знайти в цьому посиланні GitHub
Луїс Мендо

1
@DrQuarius Ні, така поведінка присутня у досить старій специфікації MATL, яку я зазвичай використовую. Ви дійсно повинні перевірити таблицю 3. Не тільки буфер обміну Jза замовчуванням містить 1j, але буфер обміну Lтакож містить багато корисних функцій індексації (зверніть увагу, що 1jдорівнює endMATL).
Санчіз

1
Крім того, не хвилюйтесь, я інженер-механік. Я думаю, що MATL (AB) має мало користі поза науковим середовищем, тому я б здогадався, що більшість гравців MATL (AB) / Octave є поза межами CS.
Санчіз

4

М , 15 14 байт

²×3’
*3Ḥ‘÷Ç
Ç¡

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

Алгоритм

Для цього використовуються раціональні та метод Ньютона. Зокрема, для введення x застосовуються перші x ітерації із початковим значенням x .

Ми намагаємося знайти конкретний корінь многочлена p (t) = t³ - t - 1 . Метод Ньютона досягає цього, приймаючи початкове значення t 0 - достатньо близьке до ρ - і рекурсивно визначаючи послідовність по
t n + 1 = t n - p (t n ) / p '(t n ) .

Оскільки p '(t) = 3t² -1 , то отримуємо
t n + 1 = t n - (t n ³ - t n - 1) / (3t n ² - 1) = (3t n ³ - t n - t n ³ + t n + 1) / (3t n ² - 1) = (2t n ³ + 1) / (3t n ² - 1) .

Зверніть увагу, що початкове наближення x поступово погіршується зі збільшенням x . Хоча вихід для x = 3 дещо менш точний, ніж вихід для x = 2 , оскільки метод Ньютона сходить квадратично до ρ , для великих значень x це не повинно бути проблемою .

Як це працює

Ç¡    Main link. Argument: x

Ç¡    Call the second helper link x times, which initial argument x.


*3Ḥ‘÷Ç  Second helper link. Argument: t

*3      Compute t³.
  Ḥ     Unhalve; yield 2t³.
   ‘    Increment; yield 2t³+1.
     Ç  Call the first helper link with argument t.
    ÷   Divide the left result by the right one.


²×3’    First helper link. Argument: t

²       Compute t².
 ×3     Compute 3t².
   ’    Decrement; yield 3t²-1.

Шкода, що ти не можеш використовувати ... µ¡...
Ерік Атголфер




1

NewStack , 14 байт

¹Fᵢ{E2x³⁺÷3x²⁻

Зламатися:

¹                Add arbitrary number 1 to the stack.
 Fᵢ{             Define for loop with a user's input amount of itterations.
    E            Define new edit for element 0 (element 0 being the 1 added. earlier).
     2x³⁺÷3x²⁻   update x to equal (2x^3+1)/(3x^2-1). (x = element 0).

Як це працює:

Формула (2x 3 +1) / (3x 2 -1) походить від спрощення методу Ньютона для рівняння x 3 = x + 1. Ви можете знайти його тут . Повторюючи цей процес, нескінченна кількість разів збігається до пластичного числа. Швидкість конвергенції досить швидка - близько 2,6 децималей за ітерацію.

INPUT ITERATION >> VALUE
0 >> 1
1 >> 1.5
2 >> 1.3478260869565217
3 >> 1.325200398950907
4 >> 1.3247181739990537
5 >> 1.3247179572447898
6 >> 1.324717957244746    <- 16 decimal precision in 6 iterations!
...
100 >> 1.324717957244746

Альтернатива Padovan послідовності, 27 25 17 байт

¹Fᵢ{[ƨ2+ƨ3]ℲƤƨ/ƨ2

Зламатися:

¹                  Append first element of Padovan sequence.
 Fᵢ{       Ⅎ       Define for loop of user's input amount of iterations.
    [ƨ2+ƨ3]        Append sum second and third to last elements.
            Ƥƨ/ƨ2  Print ratio of last two elements.

-2 байти, вибравши кращу стратегію друку

-8 байт, вибравши кращий спосіб індексувати стек

Як це працює:

Поки послідовність Падована триває, відношення двох останніх елементів сходиться до пластичного числа.

INPUT ITERATION >> VALUE
0 >> 1
1 >> 2
...
10 >> 1.3157894736842106
...
89 >> 1.324717957244746    <- 16 decimal precision in 89 iterations
...
100> > 1.324717957244746

0

Clojure, 46 байт

#(nth(iterate(fn[i](Math/pow(inc i)(/ 3)))1)%)

Використовується ітераційна формула куба-кореня. Це трохи цікавіше, але довше:

(def f #(apply comp(repeat %(fn[i](Math/pow(inc i)(/ 3))))))

((f 10)1)
1.3247179361449652

"Ви можете не припускати, що арифметика з плаваючою комою у вашій мові є довільною точністю, але натомість повинна використовувати її фактичну точність (мається на увазі, що виведення числа з плаваючою комою стане можливим лише мовами, де точність чисел з плаваючою комою може бути контролювати під час виконання) ".
Андерс Касеорг

Ой, я цього не помітив, який облом. І реалізувати кубічний корінь з BigDecimal здається досить складним.
NikoNyrh

0

Javascript, 36 байт

f=(x,n=x)=>n**3/x/x<n+x?f(x,++n):n/x

Працює так само, як і відповідь верхнього пітона. Не console.logбуло включено, тому що якщо ви працюєте f(x)в консолі, вона буде зареєстрована автоматично.

f=(x,n=x)=>n**3/x/x<n+x?f(x,++n):n/x
console.log(f(300))


0

> <> , 38 + 3 = 41 байт

11\n;
?!\}2,:01{::::}**-+0(?$-{+{1-:}

Очікує, що вхід буде присутній у стеку при запуску програми, тому +3 байти для -vпрапора.

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

Ефективно виконує двійковий пошук, щоб звузити вихідне значення. Збільшення xзбільшує кількість ітерацій, які потрібно виконати.

Редагувати: трохи відновлений розрахунок, щоб зберегти 1 байт, попередня версія:

11\n;
?!\}2,:0{::::}**$-1-0)?$-{+{1-:}


0

TI-BASIC, 21 байт

:Prompt X //Prompt for input, 3 bytes
:While X  //While X, 3 bytes
:³√(1+Y→Y //Calculate cube root of 1+Y and store to Y, 7 bytes
:DS<(X,0  //Decrement X and skip next command (which doesn't do anything), 5 bytes
:End      //End While loop, 2 bytes
:Y        //Display Y, 1 byte

Використовується ця рекурсивна формула .

Цікаво, що жорстке кодування числа та округлення дає однакове підрахунок байтів:

TI-BASIC, 21 байт

:Prompt X    //Prompt for input, 3 bytes
:.5√(3       //Store √(3)/2 to Ans, 5 bytes
:Ansֿ¹cosh(3ֿ¹coshֿ¹(3Ans //Store the plastic number to Ans, 9 bytes
:round(Ans,X //Round the plastic number X decimal digits, 4 bytes

Використовується ця тригонометрична формула .


Я не думаю, що ви можете використовувати плавці TI-BASIC тут:Your answer must work in a hypothetical variant of your language in which integers can be arbitrarily large, and memory (including stack) is unlimited. You may not assume that floating-point arithmetic in your language is arbitrarily accurate, but must instead use its actual accuracy (meaning that outputting a floating-point number is only going to be possible in languages where the accuracy of floating-point numbers can be controlled at runtime).
lirtosiast

0

C # , 317 байт

using m=System.Math;a=x=>{if(a==0)return "1/1";var d=a(x-1).Split('/');var b=int.Parse(d[0]);var c=int.Parse(d[1]);return string.Format("{0}/{1}",(2*m.Pow(b,3)+m.Pow(c,3)).ToString(new string('#',int.MaxValue.ToString().Length)),(3*m.Pow(b,2)*c-m.Pow(c,3)).ToString(new string('#',int.MaxValue.ToString().Length)));};

Він повертає результат у вигляді дробу.

Пояснення

Він використовує метод Ньютона з x ітераціями для знаходження кореня многочлена p ^ 3-p-1 = 0. Формула x_n = 1- (f (x_ (n-1))) / (f '(x_ (n-1))), а x_0 - початкова точка.

Похідна поліномів дорівнює 3p ^ 2-1, і скажімо x_ (n-1) = b / c. Тоді, використовуючи наведену формулу, отримуємо, що x_n = (2 b ^ 3 + c ^ 3) / (3 b ^ 2 cc ^ 3). Скажімо також, що ми починаємо з 1, це станеться, коли x = 2, тому що x> 1, і це ціле число. Код з відступом та коментування:

using System;
string PlasticNumber(int x)
{
    if (x == 2) 
        return "1/1";                 

//If x=2, we return our starting value, but we need to return it as a fraction

    var d = PlasticNumber(x - 1).Split('/');
    var b = System.Convert.ToInt32(d[0]);
    var c = int.Parse(d[1]);

//We parse the previous value of the fraction, and put it into two variables

    return string.Format("{0}/{1}", 
        (2 * Math.Pow(b, 3) + Math.Pow(c, 3))
        .ToString(new string('#', int.MaxValue.ToString().Length)),
        (3 * Math.Pow(b, 2) * c - Math.Pow(c, 3))
        .ToString(new string('#', int.MaxValue.ToString().Length)));

//We return the result as a fraction, but it's important not to return it in
  scientific notation, because that will cause issues in the parsing process 

}


0

Аксіома, 96 байт

h(n:NNI):Float==(n>1.E5=>-1;n:=n+1;j:=digits(n::PI);r:=solve(x^3-x=1,10.^-n);digits(j);rhs(r.1))

результати

(31) -> [h(i) for i in 0..10]
   (31)
   [1.0, 1.3, 1.33, 1.325, 1.3247, 1.32472, 1.324718, 1.324718, 1.32471796,
    1.324717957, 1.3247179572]
                                                         Type: List Float

як ви бачите, h (2) має бути 1,32, а не 1,33, тому в останніх цифрах є помилка

Тоді був би цей один зі 110 байт

g(n:NNI):Float==(n>1.E5=>-1;n:=n+1;j:=digits(n::PI);x:=sqrt(23./108);r:=(.5+x)^(1/3)+(.5-x)^(1/3);digits(j);r)

Він використовує формулу для рівняння дозволу ІІІ класу типу x ^ 3-3 * p * x-2 * q = 0 у випадку q ^ 2-p ^ 3> = 0, тобто m = sqrt (q ^ 2- p ^ 3) і x = (q + m) ^ (1/3) + (qm) ^ (1/3)

У нашому випадку r ^ 3-r-1 = 0 це можна записати як r ^ 3-3 * (1/3) r-2 * (1/2) = 0, тому p = 1/3 q = 1/2 m = 1 / 4-1 / 27 = 23/108 x = (0,5 + m) ^ (1/3) + (0,5-m) ^ (1/3)

цей, який використовує ітерацію Ньютона із початковою точкою r = 1

f(n:NNI):Float==(n>1.E5=>-1;n:=n+1;j:=digits(n::PI);e:=10^-n;r:=1.;repeat(v:=(r^3-r-1)/(3*r^2-1);abs(v)<e=>break;r:=r-v);digits(j);r)

це змінює функцію, розраховує значення для отримання одного obj з n + 1 цифр після плаваючої точки. Наприкінці значення цифр () присвоюється назад перед значенням, що визначає значення.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.