ウルトララジカルを計算する


24

ウルトララジカルとは

ultraradical実数の、または持参ラジカル五次方程式の唯一の真のルートとして定義され、X 5 + X + A = 0ax5+x+a=0

ここでは、UR()を使用して超ラジカル関数を示します。たとえば、10 5 + 10 100010 = 0 なのでUR(100010)=10です。105+10100010=0

チャレンジ

入力として実数を取り、その超ラジカルを返すか出力する完全なプログラムまたは関数を作成します。

必要条件

標準的な抜け穴は許可されていません。以下のテストケースの結果は、少なくとも有効数字6桁まで正確である必要がありますが、一般に、プログラムは有効な実数入力に対して対応する値を計算する必要があります。

テストケース

0に向かって丸められた9桁の小数部が参照用に提供されています。一部のテストケースについて説明が追加されています。

 a                         | UR(a)
---------------------------+---------------------
             0             |   0.000 000 000        # 0
             1             |  -0.754 877 (666)      # UR(a) < 0 when a > 0
            -1             |   0.754 877 (666)      # UR(a) > 0 when a < 0
             1.414 213 562 |  -0.881 616 (566)      # UR(sqrt(2))
            -2.718 281 828 |   1.100 93(2 665)      # UR(-e)
             3.141 592 653 |  -1.147 96(5 385)      # UR(pi)
            -9.515 716 566 |   1.515 71(6 566)      # 5th root of 8, fractional parts should match
            10             |  -1.533 01(2 798)
          -100             |   2.499 20(3 570)
         1 000             |  -3.977 89(9 393)
      -100 010             |  10.000 0(00 000)      # a = (-10)^5 + (-10)
 1 073 741 888             | -64.000 0(00 000)      # a = 64^5 + 64

受賞基準

すべての言語で最短の有効な提出が勝ちます。

回答:


12

Wolfram言語(Mathematica)、20バイト

Root[xx^5+x+#,1]&

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

まだビルトインですが、少なくともそうではありませんUltraRadical

(文字はJSのよう|->にMathematicaのように表示されます=>


9
Mathematicaが使用していますなぜ私が疑問に思っておくと、代わりに
アダム

2
@Adám私は最初の2つの正方形を見ることになっていますか、何らかのフォントがありません...
mbrig

6
@mbrigただの二乗。それが私のポイントです。ユニコードにほとんどの文字あります、Mathematicaはプライベート使用領域で文字を使用します。
アダム

8

Python 3.8(プレリリース)、60バイト

f=lambda n,x=0:x!=(a:=x-(x**5+x+n)/(5*x**4+1))and f(n,a)or a

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

ニュートン反復法。x=xf(x)f(x)=xx5+x+n5x4+1

4 x 5nを使用している間4x5n5x4+1は数学的に同等であり、プログラムを永久にループさせます。


その他のアプローチ:

Python 3.8(プレリリース)、102バイト

lambda x:a(x,-x*x-1,x*x+1)
a=lambda x,l,r:r<l+1e-9and l or(m:=(l+r)/2)**5+m+x>0and a(x,l,m)or a(x,m,r)

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

関数x^5+x+aが増加している場合、バイナリ検索。境界を設定する-abs(x)abs(x)十分ですが、-x*x-1x*x+1短くなっています。

ところで、Pythonの再帰制限は少し低すぎるため、1e-9が必要:=です。これはセイウチ演算子と呼ばれます。


線形検索のバイト数は少なくなりますか?
user202729

8

JavaScript(ES7)、44バイト

以下と同じ式を使用するが、反復回数が固定されたより安全なバージョン。

n=>(i=1e3,g=x=>i--?g(.8*x-n/(5*x**4+5)):x)``

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


JavaScript(ES7)、 43  42バイト

f x = 5 x 4 + 1の近似として5x4+5を使用するニュートン法。f(x)=5x4+1

n=>(g=x=>x-(x-=(x+n/(x**4+1))/5)?g(x):x)``

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

どうやって?

x0=0から始めて、再帰的に計算します。

xk+1=xkxk5+xk+n5xk4+5=xkxk+nxk4+15

xkxk+1


浮動小数点数の等価性を比較することは不正確であるため、可能なすべての入力に対してプログラムの終了を保証できるかどうかはわかりません(以下Python 3の回答では、式を短縮しようとすると問題が発生します)。
ジョエル

1
@Joelより安全なバージョンを追加しました。
アーナルド

7

ゼリー、8バイト

;17B¤ÆrḢ

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

使い方:

  • のバイナリ表現の[a, 1, 0, 0, 0, 1]先頭aに追加してリストを作成し17ます。なぜこのリストですか?探している係数に対応しているため:

    [a, 1, 0, 0, 0, 1] -> P(x) := a + 1*x^1 + 0*x^2 + 0*x^3 + 0*x^4 + 1*x^5 = a + x + x^5
    
  • 次に、Ærは、P(x) = 0係数のリスト(以前に作成したもの)が与えられると、多項式を解く組み込み関数です。

  • 実際のソリューションにのみ関心があるため、ソリューションリストの最初のエントリをで取得します。


6

APL(Dyalog Unicode)11 10 バイトSBCS

-1 dzaimaに感謝

匿名の暗黙の接頭辞関数。

(--*∘5)⍣¯1

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

()⍣¯1 次の負の暗黙関数を1回適用します。

- 否定された引数

- マイナス

*∘5 引数の5の累乗

本質的に、これは尋ねます:どのバツ にフィードする必要がありますか f(x)=xx5 such that the result becomes y.


This is very cool. Sadly J does not seem able to perform this inversion
Jonah

@dzaima Why didn't I see that‽ Thank you.
Adám

5

R, 43 bytes

function(a)nlm(function(x)abs(x^5+x+a),a)$e

Try it online!

nlm is an optimization function, so this searches for the minimum of the function x|x5+x+a|, i.e. the only zero. The second parameter of nlm is the initialization point. Interestingly, initializing at 0 fails for the last test case (presumably because of numerical precision), but initializing at a (which isn't even the right sign) succeeds.


@TheSimpliFire Mathematically, it is equivalent, but numerically, it isn't: using the square instead of the absolute value leads to the wrong value for large input. (Try it online.)
Robin Ryder

4

R, 56 bytes

function(x)(y=polyroot(c(x,1,0,0,0,1)))[abs(Im(y))<1e-9]

Try it online!

Thanks to @Roland for pointing out polyroot. I have also realised my previous answer picked a complex root for zero or negative a so now rewritten using polyroot and filtering complex roots.



@RobinRyder that’s sufficiently different that I think you should post your own answer. Thanks though!
Nick Kennedy

1
OK, thanks. Here it is.
Robin Ryder

「残念ながら」、polyrootすべての複雑なルートを返します...それ以外の場合は勝ちます。
ローランド

3

J、14バイト

{:@;@p.@,#:@17

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

Jには、多項式を解くためのビルトインがあります... p.

最後の4つのテストケースはTIOでタイムアウトしますが、理論上は依然として正しいです。

どうやって

Jの組み込みの多項式係数は、x^0最初の係数を持つ数値リストとして取得されます。つまり、リストは次のとおりです。

a 1 0 0 0 1

1 0 0 0 1バイナリで17なので、として表現し#:@17、入力を追加し,、次に適用しp.、raze ;で結果をボックス化解除し、最後の要素を取得します{:


3

Ruby, 53 41 bytes

->a{x=a/=5;99.times{x-=a/(x**4+1)+x/5};x}

Try it online!

Using Newton-Raphson with a fixed number of iterations, and the same approximation trick as Arnauld


2

Pari/GP, 34 32 26 24 bytes

a->-solve(X=0,a,a-X-X^5)

Try it online!


Nice answer, but out of curiosity: why does s(-100010) result in -8.090... - 5.877...*I instead of just 10? Is this a limitation of the language for large test cases? PS: You can save 2 bytes changing both 0.2 to .2. :)
Kevin Cruijssen

Thanks for the tip @KevinCruijssen. The issue is actually for the whole of R, but please see the workaround :)
TheSimpliFire

You can use an anonymous function: a->solve(X=-a,a,X^5+X+a).
alephalpha

Thanks @alephalpha.
TheSimpliFire


2

k4, 33 31 bytes

{{y-(x+y+*/5#y)%5+5*/4#y}[x]/x}

newton-raphson computed iteratively until a number is converged on

edit: -2 thanks to ngn!


whoops, got this all wrong...

K (oK), 10 bytes

{-x+*/5#x}

@ngn lol, that was careless... updated but now in k4 as i'm too lazy to do it in ngn/k or oK :)
scrawl

cool! the last pair of [ ] seems unnecessary
ngn

hmm, you're right. i've encountered strange behaviour before where over/converge results in an infinite loop because of extraneous/omitted (one or the other, i forget) brackets. that's why i left them in but i should have checked. thanks!
scrawl


1

C,118b/96b

#include<math.h>
double ur(double a){double x=a,t=1;while(fabs(t)>1e-6){t=x*x*x*x;t=(x*t+x+a)/(5*t+1);x-=t;}return x;}

118 bytes with original function name and with some extra accuracy (double). With bit hacks may be better, but unportable.

96 bytes with fixed iterations.

double ur(double a){double x=a,t;for(int k=0;k<99;k++){t=x*x*x*x;x=(4*x*t-a)/(5*t+1);}return x;}

Actually, our function is so good we can use better adaptations of Newton's method. Much faster and practical implementation (150 bytes) would be

#include<math.h>
double ur(double a){double x=a/5,f=1,t;while(fabs(f)>1e-6){t=x*x*x*x;f=(t*(5*t*x+5*a+6*x)+a+x)/(15*t*t-10*a*x*x*x+1);x-=f;}return x;}

I checked it works, but I'm too lazy to find out how much more fast it would be. Should be at least one more order faster as Newton's.


Would something like x-=t=... work?
user202729


0

Clean, 61 60 bytes

import StdEnv
$a=iter 99(\x=(3.0*x^5.0-a)/inc(4.0*x^4.0))0.0

Try it online!

Newton's method, first implemented in user202729's answer.

Clean, 124 bytes

import StdEnv
$a= ?a(~a)with@x=abs(x^5.0+x+a);?u v|u-d==u=u|v+d==v=v= ?(u+if(@u< @v)0.0d)(v-if(@u> @v)0.0d)where d=(v-u)/3E1

Try it online!

A "binary" search, narrowing the search area to the upper or lower 99.6% of the range between the high and low bounds at each iteration instead of 50%.




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