计算超自由基


24

什么是超自由基

ultraradical,或把基团,一个实数的被定义为五次方程的唯一实根。ax5+x+a=0

在这里,我们使用表示超自由基功能。例如,因为。UR(UR(100010)=10105+10100010=0

挑战

编写一个完整的程序或函数,将一个实数作为输入,然后返回或输出其超基数。

要求

不允许有任何标准漏洞。下面的测试用例的结果必须精确到至少6位有效数字,但通常程序应为任何有效的实数输入计算相应的值。

测试用例

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

获奖标准

每种语言中最短的有效提交时间将获胜。

Answers:


12

Wolfram语言(Mathematica),20个字节

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

在线尝试!

仍然是内置的,但至少不是UltraRadical

(字符显示方式类似于|->Mathematica,类似于=>JS)


9
我一直想知道为什么Mathematica使用替代
亚当

2
@Adám我应该只看到前两个的正方形,还是我缺少某种字体...
mbrig

6
@mbrig只是方块。这就是我的意思。即使Unicode 确实拥有大多数字符,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

使用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较短。

BTW Python的递归限制太低,因此必须具有1e-9,这:=称为walrus运算符。


线性搜索会占用更少的字节吗?
user202729

8

JavaScript(ES7),44个字节

使用与以下相同的公式但具有固定的迭代次数的更安全的版本。

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

在线尝试!


JavaScript(ES7), 43  42字节

牛顿法,使用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我添加了一个更安全的版本。
Arnauld

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 将以下默认函数负数一次应用:

- 否定论点

- 减去

*∘5 论点提高到5的幂

本质上,这会问:我需要将哪个X馈给FX=-X-X5,以便结果变为ÿ


这很酷。可悲的是,J似乎无法执行这种反转
约拿

@dzaima为什么我没有看到‽谢谢。
亚当

5

R,43个字节

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

在线尝试!

nlmx|x5+x+a|nlma


@TheSimpliFire在数学上是等效的,但在数值上却不是:对于大输入,使用平方而不是绝对值会导致错误的值。(在线尝试。
Robin Ryder


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解开结果;,然后取最后一个元素{:



2

Pari / GP34 32 26 24字节

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

在线尝试!


很好的答案,但出于好奇:为什么会s(-100010)导致结果-8.090... - 5.877...*I而不只是结果10?这是大型测试用例的语言限制吗?PS:您可以保存2个字节,将它们都更改0.2.2。:)
Kevin Cruijssen

感谢@KevinCruijssen的提示。这个问题实际上是整个[R-,但请参阅解决方法:)
TheSimpliFire

您可以使用匿名函数:a->solve(X=-a,a,X^5+X+a)
alephalpha

谢谢@alephalpha。
TheSimpliFire


2

K4,33 31个字节

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

牛顿-拉普森迭代计算,直到将一个数收敛

编辑:-2感谢ngn!


哎呀,这一切错了...

K(oK),10个字节

{-x+*/5#x}

@ngn哈哈,这是粗心的...已更新,但现在在k4中,因为我太懒了,无法在ngn / k或oK中执行它:)
抓取

凉!最后一对[ ]似乎不必要
ngn

嗯,你是对的。由于多余/遗漏了(一个或另一个,我忘记了),我在遇到过度/收敛导致无限循环之前的奇怪行为。这就是为什么我把它们留在里面,但我应该检查一下。谢谢!
乱写


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个字节,具有原始功能名称,并且具有一些额外的精度(双精度)。有了一点点黑客可能会更好,但难以移植。

固定迭代的96个字节。

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

实际上,我们的函数是如此的好,可以使用牛顿方法的更好的改编。更快,更实用的实现(150字节)将是

#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;}

我检查了它的工作原理,但是我懒得找出它要快得多。至少应该比牛顿的速度快一个订单。


x-=t=...工作吗?
user202729


0

干净61 60字节

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

在线尝试!

牛顿方法,首先在user202729的答案中实现

干净,124字节

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

在线尝试!

“二进制”搜索,在每次迭代时将搜索区域的范围缩小到上限和下限之间的上限的99.6%,而不是50%。




By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.