Calcular el ultraradical

24

¿Qué es el Ultraradical?

El ultraradical , o el radical Bring, de un número real se define como la única raíz real de la ecuación quíntica .unaX5 5+X+una=0 0

Aquí usamos para denotar la función ultraradical. Por ejemplo, , ya que .UR()UR(-100010)=10105 5+10-100010=0 0

Reto

Escriba un programa completo o una función, que tome un número real como entrada y devuelva o salga su ultraradical.

Requisitos

No se permiten lagunas estándar. Los resultados para los casos de prueba a continuación deben ser precisos al menos con 6 dígitos significativos, pero en general el programa debe calcular los valores correspondientes para cualquier entrada de número real válida.

Casos de prueba

Se dan 9 decimales redondeados hacia 0 como referencia. Se agrega explicación para algunos de los casos de prueba.

 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

Criterios ganadores

La presentación válida más corta en cada idioma gana.

Shieru Asakoto
fuente

Respuestas:

12

Wolfram Language (Mathematica) , 20 bytes

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

Pruébalo en línea!

Todavía está incorporado, pero al menos no lo es UltraRadical.

(el personaje se muestra como |->en Mathematica, similar a =>JS)

usuario202729
fuente
99
Me sigo preguntando por qué Mathematica usa y en lugar de y
Adám el
2
@ Adám, ¿se supone que debo ver cuadrados para los dos primeros, o me falta algún tipo de fuente ...
mbrig
66
@mbrig Solo cuadrados. Ese es mi punto. Mathematica utiliza caracteres en las áreas de uso privado , aunque Unicode lo hace tener la mayor parte de ellos.
Adám
8

Python 3.8 (prelanzamiento) , 60 bytes

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

Pruébalo en línea!

Método de iteración de Newton. X=X-F(X)F(X)=X-X5 5+X+norte5 5X4 4+1

Mientras usa 4 4X5 5-norte5 5X4 4+1 es matemáticamente equivalente, hace que el programa se repita para siempre.


Otro enfoque:

Python 3.8 (versión preliminar) , 102 bytes

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)

Pruébalo en línea!

Búsqueda binaria, dado que la función x^5+x+aestá aumentando. Establecer los límites a -abs(x)y abs(x)es suficiente pero -x*x-1y x*x+1es más corto.

Por cierto, el límite de recursión de Python es demasiado bajo, por lo que es necesario tener 1e-9, y :=se llama operador de morsa.

usuario202729
fuente
¿Una búsqueda lineal tomaría menos bytes?
user202729
8

JavaScript (ES7), 44 bytes

Una versión más segura con la misma fórmula que a continuación pero con un número fijo de iteraciones.

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

Pruébalo en línea!


JavaScript (ES7),  43  42 bytes

Método de Newton, usando 5 5X4 4+5 5 como una aproximación de F(X)=5 5X4 4+1 .

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

Pruébalo en línea!

¿Cómo?

Comenzamos con X0 0=0 0 y calculamos recursivamente:

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

hasta que xkxk+1 sea ​​insignificante.

Arnauld
fuente
Dado que comparar la equivalencia de números flotantes es inexacto, no estoy seguro de si se puede garantizar la terminación del programa para cada entrada posible (la respuesta de Python 3 a continuación ya presenta problemas al intentar acortar la fórmula).
Joel
1
@ Joel He agregado una versión más segura.
Arnauld
7

Jalea , 8 bytes

;17B¤ÆrḢ

Pruébalo en línea!

Cómo funciona:

  • Construye la lista [a, 1, 0, 0, 0, 1]anteponiendo aa la representación binaria de 17. ¿Por qué esta lista? Porque corresponde a los coeficientes que estamos buscando:

    [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
    
  • Entonces, Æres una función incorporada que resuelve la ecuación polinómica P(x) = 0, dada una lista de coeficientes (lo que construimos anteriormente).

  • Solo estamos interesados ​​en la solución real, por lo que tomamos la primera entrada en la lista de soluciones con .

Sr. Xcoder
fuente
6

APL (Dyalog Unicode) , 11 10 bytes SBCS

-1 gracias a dzaima

Función de prefijo tácito anónimo.

(--*∘5)⍣¯1

Pruébalo en línea!

(... )⍣¯1 aplique la siguiente función tácita negativa una vez:

- el argumento negado

- menos

*∘5 el argumento planteado al poder de 5

XF(X)=-X-X5 5y

Adán
fuente
Esto es muy genial. Lamentablemente, J no parece capaz de realizar esta inversión
Jonás
@dzaima ¿Por qué no lo vi? Gracias.
Adám
5

R , 43 bytes

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

Pruébalo en línea!

nlmXEl |X5 5+X+unaEl |nlma

Robin Ryder
fuente
@TheSimpliFire Matemáticamente, es equivalente, pero numéricamente no lo es: usar el cuadrado en lugar del valor absoluto conduce al valor incorrecto para una entrada grande. ( Pruébelo en línea. )
Robin Ryder
4

R , 56 bytes

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

Pruébalo en línea!

polyrootunapolyroot

Nick Kennedy
fuente
2
43 bytes
Robin Ryder
@RobinRyder que es lo suficientemente diferente que creo que debería publicar su propia respuesta. Gracias sin embargo!
Nick Kennedy el
1
Vale gracias. Aqui esta .
Robin Ryder
"Desafortunadamente", polyrootdevuelve todas las raíces complejas ... De lo contrario, ganaría.
Roland
3

J , 14 bytes

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

Pruébalo en línea!

J tiene un incorporado para resolver polinomios ... p.

Los últimos 4 casos de prueba caducaron en TIO, pero en teoría siguen siendo correctos.

cómo

Los coeficientes polinómicos para la construcción de J se toman como una lista numérica, con el coeficiente para el x^0primero. Esto significa que la lista es:

a 1 0 0 0 1

1 0 0 0 1es 17 en binario, así que lo representamos como #:@17, luego agregamos la entrada ,, luego aplicamos p., luego desempaquetamos los resultados con raze ;, luego tomamos el último elemento{:

Jonás
fuente
3

Ruby , 53 41 bytes

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

Pruébalo en línea!

Usando Newton-Raphson con un número fijo de iteraciones, y el mismo truco de aproximación que Arnauld

GB
fuente
2

Pari / GP , 34 32 26 24 bytes

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

Pruébalo en línea!

TheSimpliFire
fuente
Buena respuesta, pero por curiosidad: ¿por qué s(-100010)resulta en -8.090... - 5.877...*Ilugar de solo 10? ¿Es esto una limitación del lenguaje para casos de prueba grandes? PD: puede guardar 2 bytes cambiando ambos 0.2a .2. :)
Kevin Cruijssen
R-
Se puede utilizar una función anónima: a->solve(X=-a,a,X^5+X+a).
alephalpha
Gracias @alephalpha.
TheSimpliFire
2

k4, 33 31 bytes

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

newton-raphson calculó iterativamente hasta que un número converge

editar: -2 gracias a ngn!


whoops, entendí todo esto mal ...

K (oK), 10 bytes

{-x+*/5#x}
garabatear
fuente
@ngn lol, eso fue descuidado ... actualizado pero ahora en k4 ya que soy demasiado vago para hacerlo en ngn / k o oK :)
garabatea el
¡guay! el último par de [ ]parece innecesario
ngn
hmm, tienes razón He encontrado un comportamiento extraño antes donde over / converge resulta en un ciclo infinito debido a corchetes extraños / omitidos (uno u otro, lo olvido). es por eso que los dejé pero debería haberlo verificado. ¡Gracias!
garabato
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 con el nombre de la función original y con cierta precisión adicional (doble). Con bit hacks puede ser mejor, pero no portable.

96 bytes con iteraciones fijas.

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

En realidad, nuestra función es tan buena que podemos usar mejores adaptaciones del método de Newton. Una implementación mucho más rápida y práctica (150 bytes) sería

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

Verifiqué que funciona, pero soy demasiado vago para saber cuánto más rápido sería. Debería ser al menos un orden más más rápido que el de Newton.

sanaris
fuente
¿Algo le gustaría x-=t=...trabajar?
user202729
1
82 bytes
techo
0

Limpio , 61 60 bytes

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

Pruébalo en línea!

El método de Newton, implementado por primera vez en la respuesta del usuario 202729 .

Limpio , 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

Pruébalo en línea!

Una búsqueda "binaria", que reduce el área de búsqueda al 99,6% superior o inferior del rango entre los límites superior e inferior en cada iteración en lugar del 50%.

Οurous
fuente
0

Maplesoft Maple , 23 bytes

f:=a->fsolve(x^5+x+a=0)

Desafortunadamente, no hay un compilador / calculadora de arce en línea por ahí AFAIK. Pero el código es bastante sencillo.

polfosol ఠ_ఠ
fuente