Oblicz Ultraradical

24

Co to jest ultradźwiękowe

Ultraradical lub Doprowadzić rodnik liczby rzeczywistej jest zdefiniowane jako jedynym realnym korzenia Quintic równaniu .zax5+x+za=0

Tutaj używamy do oznaczenia funkcji ultraradycznej. Na przykład , ponieważ .UR()UR(-100010)=10105+10-100010=0

Wyzwanie

Napisz pełny program lub funkcję, która pobiera liczbę rzeczywistą jako dane wejściowe i zwraca lub wysyła jej wartość ultraradyczną.

Wymagania

Nie są dozwolone żadne standardowe luki. Wyniki dla poniższych przypadków testowych muszą być dokładne z co najmniej 6 cyframi znaczącymi, ale ogólnie program powinien obliczyć odpowiednie wartości dla dowolnych ważnych liczb rzeczywistych.

Przypadki testowe

Jako odniesienie podano 9 miejsc po przecinku zaokrąglonych w kierunku 0. W niektórych przypadkach testowych dodano objaśnienie.

 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

Zwycięskie kryteria

Wygrywa najkrótsze ważne zgłoszenie w każdym języku.

Shieru Asakoto
źródło

Odpowiedzi:

12

Wolfram Language (Mathematica) , 20 bajtów

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

Wypróbuj online!

Nadal jest wbudowany, ale przynajmniej tak nie jest UltraRadical.

(postać jest wyświetlana jak |->w Mathematica, podobnie jak =>w JS)

użytkownik202729
źródło
9
Zastanawiam się, dlaczego Mathematica używa i zamiast i
Adám
2
@ Adám mam po prostu zobaczyć kwadraty dla pierwszych dwóch, czy brakuje mi jakiejś czcionki ...
mbrig
6
@mbrig Po prostu kwadraty. To mój punkt. Mathematica używa znaków w prywatnych obszarach użytkowania, mimo że Unicode ma ich większość.
Adám
8

Python 3.8 (wersja wstępna) , 60 bajtów

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

Wypróbuj online!

Metoda iteracji Newtona. x=xf(x)f(x)=xx5+x+n5x4+1

Podczas używania 4x5n5x4+1 jest matematycznie równoważne, co powoduje, że program zapętla się na zawsze.


Inne podejście:

Python 3.8 (wersja wstępna) , 102 bajty

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)

Wypróbuj online!

Wyszukiwanie binarne, biorąc pod uwagę, że funkcja x^5+x+arośnie. Ustaw granice na -abs(x)i abs(x)wystarczy, ale -x*x-1i x*x+1jest krótszy.

Limit rekurencji BTW Pythona jest nieco zbyt niski, więc konieczne jest posiadanie 1e-9, i :=nazywa się to operatorem morsa.

użytkownik202729
źródło
Czy wyszukiwanie liniowe zajmie mniej bajtów?
user202729
8

JavaScript (ES7), 44 bajty

Bezpieczniejsza wersja korzystająca z tej samej formuły co poniżej, ale ze stałą liczbą iteracji.

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

Wypróbuj online!


JavaScript (ES7),  43  42 bajty

5x4+5fa(x)=5x4+1

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

Wypróbuj online!

W jaki sposób?

x0=0

xk+1=xk-xk5+xk+n5xk4+5=xk-xk+nxk4+15

xk-xk+1

Arnauld
źródło
Ponieważ porównywanie równoważności liczb zmiennoprzecinkowych jest niedokładne, nie jestem pewien, czy zakończenie programu może być zagwarantowane dla każdego możliwego wejścia (odpowiedź w Pythonie 3 poniżej już napotkała problemy przy próbie skrócenia formuły).
Joel
1
@Joel Dodałem bezpieczniejszą wersję.
Arnauld
7

Galaretka , 8 bajtów

;17B¤ÆrḢ

Wypróbuj online!

Jak to działa:

  • Konstruuje listę [a, 1, 0, 0, 0, 1], przygotowując asię do binarnej reprezentacji 17. Dlaczego ta lista? Ponieważ odpowiada to szukanym przez nas współczynnikom:

    [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
    
  • Następnie Ærjest wbudowany, który rozwiązuje równanie wielomianowe P(x) = 0, biorąc pod uwagę listę współczynników (co zbudowaliśmy wcześniej).

  • Interesuje nas tylko prawdziwe rozwiązanie, dlatego pierwszy wpis na liście rozwiązań wprowadzamy za pomocą .

Pan Xcoder
źródło
6

APL (Dyalog Unicode) , 11 10 bajtów SBCS

-1 dzięki dzaima

Anonimowa ukryta funkcja prefiksu.

(--*∘5)⍣¯1

Wypróbuj online!

()⍣¯1 Zastosuj jednorazowo następującą funkcję ukrytą:

- negowany argument

- minus

*∘5 argument podniesiony do potęgi 5

xfa(x)=-x-x5y

Adám
źródło
To jest bardzo fajne. Niestety J. wydaje się nie być w stanie wykonać tej inwersji
Jonasz
@dzaima Dlaczego tego nie widziałem‽ Dziękuję.
Adám
5

R , 43 bajty

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

Wypróbuj online!

nlmx|x5+x+za|nlma

Robin Ryder
źródło
@TheSimpliFire Matematycznie jest równoważne, ale liczbowo nie jest: użycie kwadratu zamiast wartości bezwzględnej prowadzi do niewłaściwej wartości dla dużych danych wejściowych. ( Wypróbuj online. )
Robin Ryder
4

R , 56 bajtów

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

Wypróbuj online!

polyrootzapolyroot

Nick Kennedy
źródło
2
43 bajty
Robin Ryder
@RobinRyder jest wystarczająco inny, że uważam, że powinieneś opublikować własną odpowiedź. W każdym razie dzięki!
Nick Kennedy
1
Ok dzięki. Oto ona .
Robin Ryder
„Niestety” polyrootzwraca wszystkie złożone korzenie… W przeciwnym razie wygrałby.
Roland
3

J , 14 bajtów

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

Wypróbuj online!

J ma wbudowane rozwiązanie rozwiązywania wielomianów ... p.

Ostatnie 4 przypadki testowe przekroczyły limit czasu dla TIO, ale teoretycznie są nadal poprawne.

w jaki sposób

Współczynniki wielomianowe dla wbudowanych J są traktowane jako lista numeryczna, ze współczynnikiem dla x^0pierwszego. Oznacza to, że lista jest:

a 1 0 0 0 1

1 0 0 0 1ma wartość binarną 17, więc reprezentujemy ją jako #:@17, następnie dołączamy dane wejściowe ,, następnie stosujemy p., następnie rozpakowujemy wyniki za pomocą raze ;, a następnie bierzemy ostatni element{:

Jonasz
źródło
3

Rubin , 53 41 bajtów

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

Wypróbuj online!

Używanie Newtona-Raphsona ze stałą liczbą iteracji i tą samą sztuczką przybliżającą, co Arnauld

GB
źródło
2

Pari / GP , 34 32 26 24 bajtów

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

Wypróbuj online!

TheSimpliFire
źródło
Fajna odpowiedź, ale z ciekawości: dlaczego s(-100010)skutkuje -8.090... - 5.877...*Izamiast po prostu 10? Czy jest to ograniczenie języka dla dużych przypadków testowych? PS: Możesz zapisać 2 bajty, zmieniając oba 0.2na .2. :)
Kevin Cruijssen
R-
Można użyć anonimową funkcję: a->solve(X=-a,a,X^5+X+a).
alephalpha
Dzięki @alephalpha.
TheSimpliFire
2

k4, 33 31 bajtów

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

Newton-Raphson obliczał iteracyjnie, aż liczba zostanie zbiegnięta

edycja: -2 dzięki ngn!


Ups, źle to wszystko zrozumiałem ...

K (oK), 10 bajtów

{-x+*/5#x}
bazgranina
źródło
@ngn lol, to było nieostrożne ... zaktualizowane, ale teraz w k4, ponieważ jestem zbyt leniwy, aby to zrobić w ngn / k lub oK :)
bazgroły
fajne! ostatnia para [ ]wydaje się zbędne
NGN
hmm, masz rację. Zetknąłem się z dziwnym zachowaniem, zanim over / zbieżność powoduje nieskończoną pętlę z powodu obcych / pominiętych (jednego lub drugiego, zapomnę) nawiasów. dlatego zostawiłem je, ale powinienem był to sprawdzić. dzięki!
bazgroły
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 bajtów z oryginalną nazwą funkcji iz pewną dodatkową dokładnością (podwójnie). Z bitami hacki mogą być lepsze, ale nie można ich przenosić.

96 bajtów ze stałą iteracją.

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

W rzeczywistości nasza funkcja jest tak dobra, że ​​możemy użyć lepszych adaptacji metody Newtona. Byłoby to znacznie szybsze i praktyczne wdrożenie (150 bajtów)

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

Sprawdziłem, czy to działa, ale jestem zbyt leniwy, aby dowiedzieć się, o ile to by było szybsze. Powinno być co najmniej o jedno zamówienie szybsze niż Newtona.

sanaris
źródło
Czy coś jak x-=t=...praca?
user202729
1
82 bajty
ceilingcat
0

Czysty , 61 60 bajtów

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

Wypróbuj online!

Metoda Newtona, po raz pierwszy zaimplementowana w odpowiedzi user202729 .

Czysty , 124 bajty

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

Wypróbuj online!

Wyszukiwanie „binarne”, zawężające obszar wyszukiwania do górnej lub dolnej 99,6% zakresu między górną i dolną granicą przy każdej iteracji zamiast 50%.

Obrzydliwe
źródło
0

Python 3 + sympy, 72 bajty

lambda y:float(sympy.poly("x**5+x+"+str(y)).all_roots()[0])
import sympy

Wypróbuj online!

Nick Kennedy
źródło
0

Klon Maplesoft , 23 bajty

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

Niestety nie ma online kompilatora / kalkulatora Maple AFAIK. Ale kod jest dość prosty.

polfosol ఠ_ఠ
źródło