プラスチック数の概算


24

チャレンジ

プラスチック製の番号は、多くの興味深い数学的な性質で、黄金比に関連した数です。そのため、数を計算するために使用できる多くのアプローチがあります。

この課題の目的で番号を正確に指定するために、次の定義を使用します(ただし、同等の定義は多数ありますが、同じ番号になる限り、任意の定義を使用できます)。

プラスチック数は実数であり、ρようρ ³= ρ +1。

あなたの課題は、入力として整数xを取り(x > 1で)、出力としてρの近似値を生成するプログラムまたは関数を作成し、xの値が大きくなるほど出力がρに近づくことです(せいぜい有限の例外を除いて、この目的のために「近い」と同じ値にとどまります)、任意の正の数δに対して、ρのδ内にある出力を生成するプログラムへの入力xがあります。

明確化

  • 本質的に文字列を出力するメソッド(標準出力ストリームなど)を介して出力する場合、出力を10進数(たとえば1.3247179572)でフォーマットするか、2つの整数の/間に文字を入れた比率で出力をフォーマットできます。
  • プログラミング言語内で値として出力する場合(関数から返される場合など)は、固定小数点、浮動小数点、または有理型でなければなりません。(特に、2つの整数の比率を保持するためだけに使用されない限り、数値を記号的に格納するデータ型は使用できません。したがって、Mathematicaまたは同様の言語を使用している場合は、追加の実際に出力の数字を生成するコード。)
  • あなたの答えは、整数を任意に大きくすることができ、メモリ(スタックを含む)は無制限である、あなたの言語の仮想的な変形で機能しなければなりません。言語の浮動小数点演算がarbitrarily意的に正確であると仮定することはできませんが、代わりに実際の正確さを使用する必要があります(つまり、浮動小数点数の出力は、浮動小数点数の精度が可能な言語でのみ可能になることを意味します)実行時に制御されます)。
  • xは、任意の意味を持ちます(値を大きくすると、より正確な出力が得られます)。ほとんどのサブミッションでは、生成する出力の桁数、またはプログラムがプラスチック数に収束するために使用するアルゴリズムの反復数を制御しますが、他の意味も受け入れられると思います。

テストケース

プラスチック番号の最初の数桁は次のとおりです。

1.32471795724474602596090885

OEISではさらに多くの数字を使用できます。

勝利条件

場合と同様に、バイト単位で測定した方が短い方が優れています。ただし、既存の回答に何か(たとえば、異なる言語やアルゴリズム)を追加する限り、勝たなかったとしても、回答を投稿してください。


1
ふーむ、(cbrt(108 + 12 * sqrt(69))+ cbrt(108-12 * sqrt(69)))/ 6何かbit.ly/2rCqedX ^ _ ^
DrQuarius

2
再帰/スタックの深さが無制限であると仮定することもできますか?
-xnor

2番目のポイントを明確にするために、任意の精度のライブラリ(Pythonのmpmathなど)を使用できますか?それらは補助データ型を使用しますが、それを「記号的に」格納するものとしてカウントしますか?
バットマン

1
少なくとも、答えがρに収束することを期待しています。また、「正直な」ソリューションは、テストx> y-> |ρx-ρ|に簡単に失敗する可能性があります> |ρy-ρ| 有限数の(x、y)ペアの場合。それが受け入れられない場合は、仕様でこれをより明確にする必要があると思います。
デニス

6
多くの回答者は、ρのx桁近似を計算するという(に陥りました。問題は、おそらくxが無限に多く、(x + 1)桁近似はx桁近似よりも良くないということです。これを許可するつもりだったかどうかをおそらく明確にする必要があります。そうでない場合は、「近い」を「厳密に近い」に置き換えます。そうした場合、「少なくとも近い」、または何か。また、シーケンス ρに収束するというより緩やかな要件を考慮することもできます。これにより、さらにxnorの答えが可能になります。
アンダースカセオルグ

回答:


10

Python 2、49バイト

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

オンラインでお試しください!

そのアイデアは、分母が入力精度パラメーターである分数としてρwith を表現することです。取得する分母を取り、クリアします。ρ³=ρ+1n/xx(n/x)³=n/x+1n³=x²(x+n)

LHS nはRHSよりも速く増加するため、等値点nを最小値として近似できn³≥x²(x+n)ます。コードnは、これが当てはまるまでカウントアップし、x小さいほうから開始します。

小さいバイトの保存は、両側を書き込みによって分割することですn³/x²≥x+nwhile条件で否定されます)。これはコードのフロア分割ですが、失われる小数部分は無視できます。

同じ長さの代替は、代わりに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₀| f(x + 1)−ρ| <| f(x)−ρ|)。
アンデルスカセオルグ

この問題2**input()は、単にではなく使用することで修正できますinput()。その場合、各近似値は前の近似値と同じくらい正確になります。

10

Mathematica、20バイト

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

Mathematicaの組み込みRoot関数は多項式方程式の解を提供します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 *)

サンプルI / O

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

Mathematica、27バイト

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

Martinから-1バイト、
ovsから2バイト

入力

[27]

出力

{1.32471795724474602596090885}


Solve[x^3==x+1>2,x]~N~#&24バイト
ovs

1
しかし、この結果は{{x -> 1.32...}}そうです。aisが有効な出力形式であるかどうかを確認することをお勧めします。
マーティンエンダー


まだ{1.32...}実際にはありますが、その形式はおそらくそれほど議論の余地がありません。
マーティンエンダー

1
これが有効になるように、チャレンジをもう少し一般化しました。「最初のx桁」ソリューションを禁止することを意図したものではありません。そのため、以前はそうではなかったにもかかわらず、これは今では有効です。

6

sed67 60(59 + 1)バイト

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

オンラインでお試しください!

+1 -Eフラグ(BREの代わりにERE)。入力と出力は両方とも単項です:x = 5の入力11111例:出力は2つの単項数の小数です:前述の11111入力は出力11111/1111(10進数で5/4)を生成します。

Padovanシーケンスの連続する要素間の分数としてプラスチック数を近似します


1
FWIW bコマンドの後にスペースは必要ありませんが、空のラベルを使用して(:そしてb引数なしで)短くすることができます。tio.run/#%23K05N@f@/...
ヨルダン

ああ素晴らしい。そして、のt代わりにを使用してさらに4バイトを保存できるbので、これはかなり良い保存です。ありがとう:)
FireFly

5

Mathematica、27バイト

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

ネストされた立方ラジカル形式³√(1 +³√(1 +³√(1 + ...)))の切り捨てられた近似を使用します。出力の小数点以下桁数は常にx-1ですが、式の収束は反復ごとに1桁より遅くなるため、結果は実際にはそれよりも精度が低くなります(xは計算されるネストされたラジカルの数としても使用されます)。たとえば、x = 100

_________________________________________________________________________
1.324717957244746025960908854478097340734404056901733364534015050302827850993693624204577670741656151

上線部分が正しい場合。


でこのアルゴリズムを書くことを計画しdcていましたが、立方根演算がなく、数を累乗する⅓も機能しないことが判明したため、地に陥りました:-(少なくとも、常に頼りにすることができますMathematicaに適切な

3
@ ais523実際にありCubeRootますが、そのためのバイトを得た人はいません。
マーティンエンダー

4

オクターブ、50バイト

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

オンラインでお試しください!

n目的の出力桁数を使用して、匿名関数を定義します。

この答えdigitsは、可変精度演算の桁数の現在の設定を返す悪用です。これは、「出力引数が多すぎる」というエラーなしで、匿名関数で使用できることを意味します。

それ以外は、本当に簡単vpasolveですdigits。最後の呼び出しで設定された精度で、可変精度算術ソルバの略です。以来vpaスペックごとに禁止されているオクターブ内のシンボリックデータ型で、私達はちょうど全体の機能をラップするchar(...)文字列の出力を取得します。であることに注意solveしてvpasolvef==0暗示されているので、r^3==r+1置き換えられていますr^3-r-1 (==0)


質問を行って、このような回答を許可しないように変更しました(意図していませんでした)。

@ ais523通知をありがとう!
-Sanchises

4

MATL(27 28バイト)

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

私の最初の解決策(27バイト)

オンラインでお試しください!

それは確かに最適ではありません、私はまだMATLに慣れています。

説明:

input + 3までのPadovanシーケンスを作成し、最後の2つの数値の比率を見つけます。

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設定の浮動小数点制限である任意の精度のニーズを満たしていません。したがって、この精度を拡張するために数バイトを追加するのではなく、適切な分数ルートを使用して、切り捨てられたPadovanシーケンスの(N-1)番目とN 番目の要素に最後の2つの整数の分数を書き込む方が簡単です。

例:「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念頭に置いて、あなたは置き換えることができ.With @)y@1+)+だけで@tQh)s。さらに、J配列の終わりを示すために使用できます。あなたが交換できるようにし、最終的に、MATLは、通常の配列や文字配列を区別しないYch(あなたは余分な機能を必要としませんYc)。これにより、わずか28バイトが得られます7BG:"t@tQh)sh]tJ)V47hyJq)Vh&&余分な出力を防ぎ'/'、47 で置き換えることに注意してください)。
-Sanchises

1
賞賛は、7B素朴なプッシュよりもはるかに良いlllv
-Sanchises

1
常に見つけることができる@DrQuarius最新バージョンこのGitHubのリンクに
ルイス・Mendo

1
@DrQuariusいいえ、この動作は、私が一般的に使用するかなり古いMATL仕様に存在します。本当に表3を確認する必要がありJます。デフォルトでは1j、クリップボードにが含まれているだけでなく、クリップボードLには多くの便利なインデックス関数も含まれています(MATLでは1jequals endに注意してください)。
Sanchises

1
また、心配しないでください、私は機械エンジニアです。MATL(AB)は科学的環境以外ではほとんど使用されないと思うので、MATL(AB)/ Octaveゴルファーの大半はCSの外部から来ていると思います。
Sanchises

4

M15 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、我々 GET
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

パドバンシーケンスオルタナティブ、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バイト

使い方:

Padovan配列が続き、最後の二つの要素の比は、プラスチック数に収束します。

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

「あなたの言語の浮動小数点演算がarbitrarily意的に正確であると仮定することはできませんが、代わりに実際の精度を使用する必要があります(つまり、浮動小数点数の出力は、浮動小数点数の精度が可能な言語でのみ可能になることを意味します実行時に制御されます。」
Anders Kaseorg

ああ、私はそのことに気づかなかった、なんて残念だ。また、BigDecimalでキュービックルートを実装することは非常に難しいようです。
ニコニール

0

Javascript、36バイト

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

Pythonの一番上の答えと同じように機能します。コンソールで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-:}

入力はプログラムの開始時にスタック上に存在することが予想されるため、-vフラグは+3バイトです。

オンラインでお試しください!

バイナリ検索を効果的に実行して、出力値を絞り込みます。増加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)));};

結果を分数として返します。

説明

多項式p ^ 3-p-1 = 0の根を見つけるために、ニュートン法をx回の反復で使用します。式は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.33ではなく1.32である必要があるため、最後の桁にエラーがあります

次に、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)

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でニュートン反復を使用するこの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)

関数内で変化し、floatポイントからn + 1桁の1つのobjを取得するための数字の値。最後に、digits()値がpreciding valueに割り当てられます。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.