Oblicz pierwiastek sześcienny liczby

12

Celem tego kodu golfa jest stworzenie programu lub funkcji, która oblicza i wyprowadza pierwiastek kostki z liczby podanej jako dane wejściowe.
Zasady:

  • Brak zasobów zewnętrznych
  • Bez użycia wbudowanych funkcji rootowania kostki.
  • Bez użycia metod / operatorów, które mogą podnieść liczbę do potęgi (w tym pierwiastek kwadratowy, czwarty pierwiastek itp.).
  • Twoja funkcja / program musi być w stanie akceptować liczby zmiennoprzecinkowe i liczby ujemne jako dane wejściowe.
  • Jeśli pierwiastek kostki jest liczbą zmiennoprzecinkową, zaokrąglij ją do 4 liczb po przecinku.
  • To jest golfowy kod, wygrywa najkrótszy kod w bajtach.

Przypadki testowe:

27 --> 3
64 --> 4
1  --> 1
18.609625 --> 2.65
3652264 --> 154
0.001 --> 0.1
7  --> 1.9129

Możesz użyć wszystkich powyższych przypadków testowych do testowania liczb ujemnych ( -27 --> -3, -64 --> -4...)

ProgramFOX
źródło
cholera, jeśli pozwoliłbyś tylko na liczby z precyzyjną kostką, miałbym fajnego golfa
yo
1
Sądząc z przypadków testowych, zakładam, że program musi zajmować się tylko liczbami rzeczywistymi?
user12205
@ace dodaje kompleks i zmieniam 2 litery w kodzie;)
yo
2
Czy zaokrąglanie do 4 cyfr po przecinku jest silnym wymogiem? Czy może to być coś w rodzaju „nie musisz wyświetlać więcej niż 4 cyfry po przecinku”?
Victor Stafusa
W odniesieniu do mojej odpowiedzi przy użyciu Exp (ln (x) / 3) (i kilku jej klonów) proszę wyjaśnić, czy Exp jest dozwolony. Zakładam, że pow (x, 1/3) nie jest (chociaż technicznie nie jest to funkcja pierwiastka sześcianu).
Level River St

Odpowiedzi:

6

J: 16 znaków

Luźne tłumaczenie odpowiedzi Haskella:

-:@((%*~)+])^:_~

Przypadki testowe:

   -:@((%*~)+])^:_~27
3
   -:@((%*~)+])^:_~64
4
   -:@((%*~)+])^:_~1
1
   -:@((%*~)+])^:_~18.609625
2.65
   -:@((%*~)+])^:_~3652264
154
   -:@((%*~)+])^:_~0.001
0.1
   -:@((%*~)+])^:_~7
1.91293

Działa to tak:

     (-:@((% *~) + ])^:_)~ 27
↔ 27 (-:@((% *~) + ])^:_) 27
↔ 27 (-:@((% *~) + ])^:_) 27 (-:@((% *~) + ])) 27
↔ 27 (-:@((% *~) + ])^:_) -: ((27 % 27 * 27) + 27)
↔ 27 (-:@((% *~) + ])^:_) 13.5185
↔ 27 (-:@((% *~) + ])^:_) 27 (-:@((% *~) + ])) 13.5185
↔ 27 (-:@((% *~) + ])^:_) -: ((27 % 13.5185 * 13.5185) + 13.5185)
↔ 27 (-:@((% *~) + ])^:_) 6.83313
...

W słowach:

half =. -:
of =. @
divideBy =. %
times =. *
add =. +
right =. ]
iterate =. ^:
infinite =. _
fixpoint =. iterate infinite
by_self =. ~

-:@((%*~)+])^:_~ ↔ half of ((divideBy times by_self) add right) fixpoint by_self

Nie jest to jedno z najlepszych nieporadnych tłumaczeń, ponieważ ~na końcu widmowy widelec .

James Wood
źródło
19

Haskell - 35

c n=(iterate(\x->(x+n/x/x)/2)n)!!99

Przykładowe przebiegi:

c 27  =>  3.0
c 64  =>  4.0
c 1  =>  1.0
c 18.609625  =>  2.6500000000000004  # only first 4 digits are important, right?
c 3652264  =>  154.0
c 0.001  =>  0.1
c 7  =>  1.9129311827723892
c (-27)  =>  -3.0
c (-64)  =>  -4.0

Co więcej, jeśli zaimportujesz Data.Complex, działa nawet na liczbach zespolonych, zwraca jeden z pierwiastków liczby (są 3):

c (18:+26)  =>  3.0 :+ 1.0

:+Operator powinien być odczytywany jako „plusa I czasy”

mniip
źródło
1
To zasługuje na +1. Przez ostatnią godzinę refaktoryzowałem uogólnione n-te glony korzeniowe i właśnie doszedłem do tego samego rezultatu. Brawo.
primo
@primo Natychmiast przypomniałem sobie wszystkie n-te algorytmy aproksymacji roota i po rezygnacji z serii Taylor / Maclaurin w APL wykorzystałem to.
mniip
Korzystając z metody Newtona, którą dostałem x=(2*x+n/x/x)/3, czy możesz wyjaśnić, dlaczego możesz jej użyć x=(x+n/x/x)/2? Zbiega się wolniej, ale nie potrafię wyjaśnić, dlaczego się zbiega ...
Michael M.
@Michael, ponieważ jeśli weźmiesz x=cbrt(n), x=(x+n/x/x)/2to prawda. Tak jest w przypadku twojego wyrażenia
mniip
@Michael Dostałem się w ten sposób: codepad.org/gwMWniZB
primo
7

SageMath, (69) 62 bajty

Jednak nigdy nie wierz, że to da ci wynik, bardzo trudno jest przejść losowo przez wszystkie liczby:

def r(x):
 y=0
 while y*y*y-x:y=RR.random_element()
 return "%.4f"%y

jeśli nie nalegałeś na obcinanie:

def r(x):
 y=0
 while y*y*y-x:y=RR.random_element()
 return y

SageMath, 12 bajtów, jeśli expjest dozwolone

Działa dla wszystkich rzeczy: pozytywne, negatywne, zero, złożone, ...

exp(ln(x)/3)
Siema'
źródło
Uważam, że używasz operatora, który może podnieść liczbę do potęgi.
user12205
ah ok, racja, zredagowano
yo
6
+1 za monumentalnie głupi algorytm, który wciąż spełnia wymagania.
Ślimak mechaniczny
@Mechanicalsnail Thanks. Mam nadzieję, że to oczywiste, że to, co robię, jest rodzajem recesji: D Jednakże, jeśli expjest to dozwolone, mam mniej niż 12 lat i wcale nie jestem głupia :)
yo
Biorąc pod uwagę, że expjest to skrót od „funkcji wykładniczej”, która jest „funkcją, której wartość jest stałą podniesioną do potęgi argumentu, szczególnie funkcją, w której stała jest równa e.”, I „Nie ma zastosowania metod / operatorów, które może podnieść liczbę do potęgi ”, expnie jest dozwolone.
mbomb007
5

Python - 62 bajty

x=v=input()
exec"x*=(2.*v+x*x*x)/(v+2*x*x*x or 1);"*99;print x

Ocenia pełną precyzję zmiennoprzecinkową. Zastosowana metoda jest metodą Halleya . Ponieważ każda iteracja daje 3 razy więcej poprawnych cyfr niż ostatnia, 99 iteracji to trochę przesada.

Wejście wyjście:

27 -> 3.0
64 -> 4.0
1 -> 1.0
18.609625 -> 2.65
3652264 -> 154.0
0.001 -> 0.1
7 -> 1.91293118277
0 -> 1.57772181044e-30
-2 -> -1.25992104989
primo
źródło
Jak to działa?
justhalf
1
@ justhalf Myślę, że w zasadzie jest to metoda aproksymacji Newtona.
jo
Btw, kończy się niepowodzeniem0
yo
Nie działa -2, przepraszam za to.
jo
3
@plg Opis problemu zabrania używania jakiejkolwiek funkcji wykładniczej, w przeciwnym razie v**(1/.3)byłby pewnym zwycięzcą.
primo
3

JavaScript (55)

function f(n){for(i=x=99;i--;)x=(2*x+n/x/x)/3;return x}

BONUS, Ogólne sformułowanie dla wszystkich korzeni
function f(n,p){for(i=x=99;i--;)x=x-(x-n/Math.pow(x,p-1))/p;return x}

W przypadku pierwiastka sześciennego wystarczy użyć f(n,3), pierwiastek kwadratowy f(n,2)itp. Przykład: f(1024,10)zwraca 2.

Objaśnienie
Na podstawie metody Newtona:

Znajdź: f(x) = x^3 - n = 0rozwiązaniem jest n = x^3
Wyprowadzenie:f'(x) = 3*x^2

Iteracja:
x(i+1) = x(i) - f(x(i))/f'(x(i)) = x(i) + (2/3)*x + (1/3)*n/x^2

Testy

[27,64,1,18.609625,3652264,0.001,7].forEach(function(n){console.log(n + ' (' + -n + ') => ' + f(n) + ' ('+ f(-n) +')')})

27 (-27) => 3 (-3)
64 (-64) => 4 (-4)
1 (-1) => 1 (-1)
18.609625 (-18.609625) => 2.65 (-2.65)
3652264 (-3652264) => 154 (-154)
0.001 (-0.001) => 0.09999999999999999 (-0.09999999999999999)
7 (-7) => 1.912931182772389 (-1.912931182772389) 
Michael M.
źródło
Jedna postać krótsza:function f(n){for(i=x=99;i--;)x-=(x-n/x/x)/3;return x}
skopiuj
Można zmniejszyć do 47 bajtówf=(n)=>eval('for(i=x=99;i--;)x=(2*x+n/x/x)/3')
Luis Felipe De Jesus Munoz
2

PHP - 81 bajtów

Iteracyjne rozwiązanie:

$i=0;while(($y=abs($x=$argv[1]))-$i*$i*$i>1e-4)$i+=1e-5;@print $y/$x*round($i,4);
Razvan
źródło
Co się stanie, jeśli spróbuje obliczyć pierwiastek sześcienny zera?
Victor Stafusa
Po prostu wyświetli „0” (dzięki operatorowi eliminacji błędów - „@”).
Razvan
1
0.0001może być zastąpiony przez 1e-4i 0.00001przez 1e.5.
ComFreek
Wymaga to PHP <7 ( 0/0daje NANw PHP 7). $i=0;jest niepotrzebne (-5 bajtów. Gdyby nie było, forzaoszczędziłby jeden bajt.) Miejsce po printnie jest wymagane (-1 bajt). -Rmożna zapisać 3 bajty za pomocą $argn.
Tytus
Zapisz parę nawiasów z while(1e-4+$i*$i*$i<$y=abs($x=$argn))(-2 bajty).
Tytus
2

Perl, 92 bajty

sub a{$x=1;while($d=($x-$_[0]/$x/$x)/3,abs$d>1e-9){$x-=$d}$_=sprintf'%.4f',$x;s/\.?0*$//;$_}
  • Funkcja azwraca ciąg znaków z liczbą bez niepotrzebnej części ułamkowej lub nieznacznych zer na prawym końcu.

Wynik:

              27 --> 3
             -27 --> -3
              64 --> 4
             -64 --> -4
               1 --> 1
              -1 --> -1
       18.609625 --> 2.65
      -18.609625 --> -2.65
         3652264 --> 154
        -3652264 --> -154
           0.001 --> 0.1
          -0.001 --> -0.1
               7 --> 1.9129
              -7 --> -1.9129
 0.0000000000002 --> 0.0001
-0.0000000000002 --> -0.0001
               0 --> 0
              -0 --> 0

Wygenerowane przez

sub test{
    my $a = shift;
    printf "%16s --> %s\n", $a, a($a);
    printf "%16s --> %s\n", "-$a", a(-$a);
}
test 27;
test 64;
test 1;
test 18.609625;
test 3652264;
test 0.001;
test 7;
test "0.0000000000002";
test 0;

Obliczenia oparte są na metodzie Newtona :

Obliczenie

Heiko Oberdiek
źródło
2

APL - 31

(×X)×+/1,(×\99⍴(⍟|X←⎕)÷3)÷×\⍳99

Wykorzystuje fakt, że cbrt(x)=e^(ln(x)/3)zamiast naiwnego potęgowania oblicza się e^xza pomocą serii Taylor / Maclaurin.

Przykładowe przebiegi:

⎕: 27
3
⎕: 64
4
⎕: 1
1
⎕: 18.609625
2.65
⎕: 3652264
154
⎕: 0.001
0.1
⎕: 7
1.912931183
⎕: ¯27
¯3
⎕: ¯7
¯1.912931183

Widząc odpowiedź J w 16 znakach, muszę być naprawdę okropny w APL ...

mniip
źródło
2

Java, 207 182 181

Czasami, gdy gram w golfa, mam dwa piwa i gram bardzo źle

class n{public static void main(String[]a){double d=Double.valueOf(a[0]);double i=d;for(int j=0;j<99;j++)i=(d/(i*i)+(2.0*i))/3.0;System.out.println((double)Math.round(i*1e4)/1e4);}}

Iteracyjna metoda aproksymacji Newtona, wykonuje 99 iteracji.

Oto unGolfed:

class n{
    public static void main(String a[]){
        //assuming the input value is the first parameter of the input
        //arguments as a String, get the Double value of it
        double d=Double.valueOf(a[0]);
        //Newton's method needs a guess at a starting point for the 
        //iterative approximation, there are much better ways at 
        //going about this, but this is by far the simplest. Given
        //the nature of the problem, it should suffice fine with 99 iterations
        double i=d;

        //make successive better approximations, do it 99 times
        for(int j=0;j<99;j++){
            i=( (d/(i*i)) + (2.0*i) ) / 3.0;
        }
        //print out the answer to standard out
        //also need to round off the double to meet the requirements
        //of the problem.  Short and sweet method of rounding:
        System.out.println( (double)Math.round(i*10000.0) / 10000.0 );
    }
}
md_rasler
źródło
1
Możesz zmienić nazwę argszmiennej na zmniej więcej 6 znaków. Możesz usunąć przestrzeń i nawiasy klamrowe w korpusie pętli for, zmniejszając 3 znaki. Można zastąpić 10000.0przez 1e4, zmniejszając 6 znaków. Klasa nie musi być publiczna, więc możesz zredukować więcej 7 znaków. W ten sposób zostanie zredukowany do 185 znaków.
Victor Stafusa
Czy obsada na końcu jest naprawdę konieczna? To nie dla mnie.
Victor Stafusa
@Victor Dzięki za dobre oko użycie notacji E dla podwójnego 10000.0 było spektakularnie dobrym pomysłem. Według projektu pytania uważam za słuszne uczynienie z tej metody metody zamiast działającej klasy cli, co znacznie zmniejszyłoby rozmiar. W Javie nie sądziłem, że mam szansę, więc popełniłem błąd po stronie funkcjonalności.
md_rasler
Witamy w CodeGolf! Nie zapomnij dodać w odpowiedzi wyjaśnienia, jak to działa!
Justin
@Quincunx, Dzięki, dokonałem zalecanej zmiany.
md_rasler
2

TI-Basic, 26 24 bajtów

Input :1:For(I,1,9:2Ans/3+X/(3AnsAns:End
Timtech
źródło
To bezpośrednio wykorzystuje ^operatora, prawda? Jest to zabronione przez zasady
mniip
@mniip: Czy e^jest pojedynczy operator w serii TI-83? Nie pamiętam Tak czy inaczej, narusza to ducha zasad.
Ślimak mechaniczny
@Mechanicalsnail To nie ma znaczenia, powiedziałbym. W większości języków możesz po prostu to zrobić exp(ln(x)/3)lub e^(ln(x/3))jeśli zezwolisz na którykolwiek z tych dwóch. Ale jakoś rozumiem, że exp(ln(x)/a)jest to zbyt ekwiwalent, aby x^(1/a)pozwalały na to reguły: - /
yo
Funkcja wykładnicza: „funkcja, której wartość jest stałą podniesioną do potęgi argumentu , szczególnie funkcja, w której stała wynosi e”. ... „Bez użycia metod / operatorów, które mogą podnieść liczbę do władzy”
mbomb007
Dzięki za catch @ mbomb007, napisałem tę odpowiedź ponad 3 lata temu i naprawię ją, aby była zgodna teraz.
Timtech
2

Js 57 bajtów

f=(x)=>eval('for(w=0;w**3<1e12*x;w++);x<0?-f(-x):w/1e4')

f=(x)=>eval('for(w=0;w**3<1e12*x;w++);x<0?-f(-x):w/1e4')
document.getElementById('div').innerHTML += f(-27) + '<br>'
document.getElementById('div').innerHTML += f(-64) + '<br>'
document.getElementById('div').innerHTML += f(-1) + '<br>'
document.getElementById('div').innerHTML += f(-18.609625) + '<br>'
document.getElementById('div').innerHTML += f(-3652264) + '<br>'
document.getElementById('div').innerHTML += f(-0.001) + '<br>'
document.getElementById('div').innerHTML += f(-7) + '<br><hr>'
document.getElementById('div').innerHTML += f(27) + '<br>'
document.getElementById('div').innerHTML += f(64) + '<br>'
document.getElementById('div').innerHTML += f(1) + '<br>'
document.getElementById('div').innerHTML += f(18.609625) + '<br>'
document.getElementById('div').innerHTML += f(3652264) + '<br>'
document.getElementById('div').innerHTML += f(0.001) + '<br>'
document.getElementById('div').innerHTML += f(7) + '<br>'
<div id="div"></div>

Luis Felipe De Jesus Munoz
źródło
2

JavaScript: 73/72 znaków

Ten algorytm jest kiepski i wykorzystuje fakt, że pytanie to jest ograniczone do 4 cyfr po przecinku. Jest to zmodyfikowana wersja algorytmu, którą zasugerowałem w piaskownicy w celu przerobienia pytania. Liczy się od zera do nieskończoności h*h*h<a, wystarczy sztuczka mnożenia i dzielenia, aby obsłużyć precyzję 4 cyfr dziesiętnych.

function g(a){if(a<0)return-g(-a);for(h=0;h*h*h<1e12*a;h++);return h/1e4}

Edytuj, 4 lata później: zgodnie z sugestią Luisa Felipe De Jesus Munoza, użycie **kodu jest krótsze, ale ta funkcja nie była dostępna w 2014 roku, kiedy napisałem tę odpowiedź. W każdym razie, używając go, golimy dodatkową postać:

function g(a){if(a<0)return-g(-a);for(h=0;h**3<1e12*a;h++);return h/1e4}
Victor Stafusa
źródło
1
Zamiast tego h*h*hmożesz zrobić h**3i zapisać 1 bajt
Luis Felipe De Jesus Munoz
@LuisfelipeDejesusMunoz Ta odpowiedź pochodzi z 2014 r. **Operator został zaproponowany w 2015 r. I został zaakceptowany jako część ECMAScript 7 w 2016 r. W chwili, gdy to napisałem, nie było tego **w języku.
Victor Stafusa,
1

JavaScript - 157 znaków

Ta funkcja:

  • Obsługa liczb ujemnych.
  • Obsługa liczb zmiennoprzecinkowych.
  • Wykonaj szybko dla dowolnej liczby wejściowej.
  • Ma maksymalną dokładność dozwoloną dla liczb zmiennoprzecinkowych javascript.
function f(a){if(p=q=a<=1)return a<0?-f(-a):a==0|a==1?a:1/f(1/a);for(v=u=1;v*v*v<a;v*=2);while(u!=p|v!=q){p=u;q=v;k=(u+v)/2;if(k*k*k>a)v=k;else u=k}return u}

Wersja objaśniona bez golfa:

function f(a) {
  if (p = q = a <= 1) return a < 0 ? -f(-a)      // if a < 0, it is the negative of the positive cube root.
                           : a == 0 | a == 1 ? a // if a is 0 or 1, its cube root is too.
                           : 1 / f (1 / a);      // if a < 1 (and a > 0) invert the number and return the inverse of the result.

  // Now, we only need to handle positive numbers > 1.

  // Start u and v with 1, and double v until it becomes a power of 2 greater than the given number.
  for (v = u = 1; v * v * v < a; v *= 2);

  // Bisects the u-v interval iteratively while u or v are changing, which means that we still did not reached the precision limit.
  // Use p and q to keep track of the last values of u and v so we are able to detect the change.
  while (u != p | v != q) {
    p = u;
    q = v;
    k = (u + v) / 2;
    if (k * k * k > a)
      v=k;
    else
      u=k
  }

  // At this point u <= cbrt(a) and v >= cbrt(a) and they are the closest that is possible to the true result that is possible using javascript-floating point precision.
  // If u == v then we have an exact cube root.
  // Return u because if u != v, u < cbrt(a), i.e. it is rounded towards zero.
  return u
}
Victor Stafusa
źródło
1

PHP, 61

Na podstawie metody Newtona. Nieznacznie zmodyfikowana wersja odpowiedzi Michaela :

for($i=$x=1;$i++<99;)$x=(2*$x+$n/$x/$x)/3;echo round($x,14);

Działa z liczbami ujemnymi, może obsługiwać liczby zmiennoprzecinkowe i zaokrągla wynik do 4 liczb po przecinku, jeśli wynikiem jest liczba zmiennoprzecinkowa.

Działające demo

Amal Murali
źródło
Możesz zapisać dwa bajty za pomocą for($x=1;++$i<100;).... Ale używanie predefiniowanych zmiennych jako danych wejściowych jest zasadniczo niezadowolone . Lepsze wykorzystanie $argv[1]lub $argn.
Tytus
1

Befunge 98 - Prace w toku

Ten język nie obsługuje liczb zmiennoprzecinkowych; to próbuje je naśladować. Obecnie działa dla liczb dodatnich, które nie zaczynają się 0po przecinku (głównie). Jednak wyświetla tylko 2 miejsca po przecinku.

&5ka5k*&+00pv
:::**00g`!jv>1+
/.'.,aa*%.@>1-:aa*

Działa poprzez wprowadzenie części przed kropką dziesiętną, pomnożenie jej przez 100000, a następnie wprowadzenie części po kropce i dodanie dwóch liczb razem. Druga linia robi licznik, dopóki kostka nie będzie większa niż wprowadzona liczba. Następnie trzeci wiersz wyodrębnia liczbę dziesiętną z liczby całkowitej.

Jeśli ktoś może mi powiedzieć, dlaczego trzeci wiersz dzieli tylko, 100aby uzyskać prawidłowe wartości, proszę mi powiedzieć.

IO:

27.0       3 .0
64.0       4 .0
1.0        1 .0
18.609625  2 .65
0.001      0 .1
7.0        1 .91

0.1        0 .1
Justin
źródło
1

Smalltalk, 37

uznanie dla algorytmu dla mniip; Wersja Smalltalk jego kodu:

wejście w n; wyjście w x:

1to:(x:=99)do:[:i|x:=2*x+(n/x/x)/3.0]

lub jako blok

[:n|1to:(x:=99)do:[:i|x:=2*x+(n/x/x)/3.0].x]
blabla999
źródło
1

GameMaker Language, 51 bajtów

for(i=x=1;i++<99;1)x=(2*x+argument0/x/x)/3;return x
Timtech
źródło
0

Haskell: 99 ° C

Nie można pokonać sprytem @mniip. Właśnie przeszedłem wyszukiwanie binarne.

c x=d 0 x x
d l h x
 |abs(x-c)<=t=m
 |c < x=d m h x
 |True=d l m x
 where m=(l+h)/2;c=m*m*m;t=1e-4

Nie golfowany:

-- just calls the helper function below
cubeRoot x = cubeRoot' 0 x x

cubeRoot' lo hi x
    | abs(x-c) <= tol = mid           -- if our guess is within the tolerance, accept it
    | c < x = cubeRoot' mid hi x      -- shot too low, narrow our search space to upper end
    | otherwise = cubeRoot' lo mid x  -- shot too high, narrow search space to lower end
    where
        mid = (lo+hi)/2
        cubed = mid*mid*mid
        tol = 0.0001
Danmcardle
źródło
Możesz użyć operatora infix dla d(jak (l#h)x), aby zapisać bajt dla każdego połączenia. cwtedy staje się id>>=(0#).
Esolanging Fruit
Możesz usunąć spacje wokół c < x.
Esolanging Fruit
Możesz użyć 1>0zamiast True.
Esolanging Fruit
0

J 28

*@[*(3%~+:@]+(%*~@]))^:_&|&1

Przy użyciu metody Newtona znalezienie źródła x^3 - Xkroku aktualizacji to x - (x^3 - C)/(3*x^2), gdzie x oznacza bieżącą domysł, a C wejście. Wykonywanie matematyki na tym daje absurdalnie prosty wyraz (2*x+C/x^2) /3. Należy zwrócić uwagę na liczby ujemne.

Zaimplementowane w J, od prawej do lewej:

  1. | Weź abs obu argumentów, przekaż je dalej
  2. ^:_ Czyń aż do konwergencji
  3. (%*~@])jest C / x^2( *~ yjest równoważne y * y)
  4. +:@] jest 2 x
  5. 3%~podziel przez trzy. Daje to pozytywne korzenie
  6. *@[ * positive_root zwielokrotnia korzeń dodatni przez znak C.

Testowe uruchomienie:

   NB. give it a name:
   c=: *@[*(3%~+:@]+(%*~@]))^:_&|&1
   c 27 64 1 18.609625 3652264 0.001 7
3 4 1 2.65 154 0.1 1.91293
jpjacobs
źródło
0

AWK, 53 bajty

{for(n=x=$1;y-x;){y=x;x=(2*x+n/x/x)/3}printf"%.4g",y}

Przykładowe użycie:

$ awk '{for(n=x=$1;y-x;){y=x;x=(2*x+n/x/x)/3}printf"%.4g",y}' <<< 18.609625 
2.65$

Dziękujemy na @Mig za JavaScriptrozwiązanie, z którego pochodzi. Działa zaskakująco szybko, ponieważ forpętla wymaga iteracji, aby przestała się zmieniać.

Robert Benson
źródło
0

C, 69 bajtów

i;float g(float x){for(float y=x;++i%999;x=x*2/3+y/3/x/x);return x;}

Kolejna implementacja metody Newtona. Wypróbuj online!

sufitowy
źródło
0

Stax , 10 bajtów CP437

╘♀┘A╕äO¶∩'

Uruchom i debuguj online!

Wyjaśnienie

Używa rozpakowanej wersji do wyjaśnienia.

gpJux*_+h4je
gp              Iterate until a fixed point is found, output the fix point
  Ju            Inverse of square
    x*          Multiplied by input
      _+h       Average of the value computed by last command and the value at current iteration
         4je    Round to 4 decimal digits
Weijun Zhou
źródło
0

Rozwiązanie JAVA

public BigDecimal cubeRoot (liczba BigDecimal) {

    if(number == null || number.intValue() == 0) return BigDecimal.ZERO;
    BigDecimal absNum = number.abs();
    BigDecimal t;
    BigDecimal root =  absNum.divide(BigDecimal.valueOf(3), MathContext.DECIMAL128);


    do {

        t = root;
        root = root.multiply(BigDecimal.valueOf(2))
                .add(absNum.divide(root.multiply(root), MathContext.DECIMAL128))
                .divide(BigDecimal.valueOf(3), MathContext.DECIMAL128);

    } while (t.toBigInteger().subtract(root.toBigInteger()).intValue() != 0);

    return root.multiply(number.divide(absNum), MathContext.DECIMAL128);
}
Ramanathan Ganesan
źródło
1
Witamy w PPCG! Jest to wyzwanie polegające na kodzie golfowym , co oznacza, że ​​celem jest rozwiązanie jak najmniejszej ilości kodu (liczonego w bajtach pliku źródłowego). Powinieneś wykazać się pewnym wysiłkiem w kierunku optymalizacji rozwiązania w tym celu i uwzględnić liczbę bajtów w swojej odpowiedzi.
Martin Ender
0

Rozwiązanie Python

def cube_root(num):
    if num == 0:
        return 0

    t = 0
    absNum = abs(num)
    root = absNum/3

    while (t - root) != 0:
        t = root
        root = (1/3) * ((2 * root) + absNum/(root * root))

    return root * (num / absNum)
Ramanathan Ganesan
źródło