Tính toán khối lập phương của một số


12

Mục tiêu của môn đánh gôn này là tạo ra một chương trình hoặc hàm tính toán và xuất ra khối lập phương của một số được đưa ra làm đầu vào.
Những quy định:

  • Không có tài nguyên bên ngoài
  • Không sử dụng các chức năng root cube tích hợp.
  • Không sử dụng các phương thức / toán tử có thể nâng một số thành lũy thừa (bao gồm căn bậc hai, căn bậc 4, v.v.).
  • Chức năng / chương trình của bạn phải có thể chấp nhận số dấu phẩy động và số âm làm đầu vào.
  • Nếu căn bậc ba là một số có dấu phẩy động, thì làm tròn nó thành 4 số sau dấu thập phân.
  • Đây là một mã golf, mã ngắn nhất tính bằng byte thắng.

Các trường hợp thử nghiệm:

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

Bạn có thể sử dụng tất cả các trường hợp thử nghiệm ở trên để kiểm tra các số âm ( -27 --> -3, -64 --> -4...)


chết tiệt, nếu bạn chỉ cho phép các số có khối chính xác, tôi sẽ có một sân golf đẹp
yo '

1
Đánh giá từ các trường hợp thử nghiệm của bạn Tôi cho rằng chương trình chỉ cần xử lý số thực?
dùng12205

@ace thêm phức tạp và tôi thay đổi 2 chữ cái trong mã của mình;)
yo

2
Là làm tròn đến 4 chữ số sau dấu thập phân là một yêu cầu mạnh mẽ? Hoặc có thể là một cái gì đó như "bạn không cần phải hiển thị hơn 4 chữ số sau dấu thập phân"?
Victor Stafusa

Với tham chiếu đến câu trả lời của tôi bằng Exp (ln (x) / 3) (và một số bản sao của nó), vui lòng làm rõ nếu Exp được cho phép. Tôi giả sử pow (x, 1/3) không phải (mặc dù về mặt kỹ thuật nó không phải là chức năng gốc khối.)
Level River St

Câu trả lời:


6

J: 16 ký tự

Bản dịch lỏng của câu trả lời Haskell:

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

Các trường hợp thử nghiệm:

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

Nó hoạt động như thế này:

     (-:@((% *~) + ])^:_)~ 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
...

Trong các từ:

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

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

Không phải là một trong những bản dịch hay nhất, vì có một ngã ba dyadic và một ~quyền ở cuối.


19

Haskell - 35

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

Ví dụ chạy:

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

Hơn nữa, nếu bạn nhập Data.Complex, nó thậm chí hoạt động trên các số phức, nó sẽ trả về một trong những gốc của số (có 3):

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

Các :+nhà điều hành cần được đọc là 'cộng với tôi lần'


1
Điều này xứng đáng +1. Tôi đã tái cấu trúc các thuật toán gốc thứ n trong một giờ vừa qua và bây giờ tôi đã đạt được kết quả tương tự. Bravo.
primo

@primo Tôi đã ngay lập tức nhớ lại tất cả các thuật toán xấp xỉ gốc thứ n, và sau khi từ bỏ loạt Taylor / Maclaurin trong APL, tôi đã sử dụng thuật toán này.
mniip

Sử dụng phương pháp Newton tôi có x=(2*x+n/x/x)/3, bạn có thể giải thích tại sao bạn có thể sử dụng x=(x+n/x/x)/2? Nó hội tụ chậm hơn nhưng tôi không thể giải thích tại sao nó hội tụ ...
Michael M.

@Michael vì nếu bạn lấy x=cbrt(n)thì x=(x+n/x/x)/2đúng. Điều đó có đúng với biểu hiện của bạn không
mniip 22/214

@Michael Tôi đã đến đó theo cách này: codepad.org/gwMWniZB
primo

7

SageMath, (69) 62 byte

Tuy nhiên, đừng bao giờ tin rằng nó sẽ mang lại cho bạn kết quả, rất khó để đi ngẫu nhiên qua tất cả các con số:

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

nếu bạn không khăng khăng cắt ngắn:

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

SageMath, 12 byte, nếu expđược phép

Hoạt động cho tất cả mọi thứ: tích cực, tiêu cực, không, phức tạp, ...

exp(ln(x)/3)

Tôi tin rằng bạn đang sử dụng một toán tử có thể nâng một số lên một sức mạnh.
dùng12205

ah ok, đúng, đã chỉnh sửa
yo '

6
+1 cho một thuật toán ngu ngốc mà vẫn đáp ứng các yêu cầu.
Ốc cơ khí

@M cơ chế cảm ơn. Tôi hy vọng rõ ràng rằng những gì tôi làm là một loại suy thoái: D Tuy nhiên, nếu expđược cho phép, tôi xuống còn 12 và không ngu ngốc chút nào :)
yo '

Xem xét đó explà viết tắt của "hàm số mũ", đó là "hàm có giá trị là hằng số được nâng lên thành sức mạnh của đối số, đặc biệt là hàm có hằng số là e." Và có "Không sử dụng các phương thức / toán tử có thể tăng một con số lên một sức mạnh ", expkhông được phép.
mbomb007

5

Python - 62 byte

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

Đánh giá chính xác điểm nổi đầy đủ. Phương pháp được sử dụng là phương pháp của Halley . Vì mỗi lần lặp lại tạo ra số chữ số chính xác gấp 3 lần số cuối cùng, 99 lần lặp là một chút quá mức cần thiết.

Đầu ra đầu vào:

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

Cái này hoạt động ra sao?
vừa rồi

1
@justhalf Tôi nghĩ rằng đây là phương pháp gần đúng của Newton.
yo '

Btw, thất bại vào0
yo '

Thất bại -2, xin lỗi vì điều đó.
yo '

3
@plg Mô tả vấn đề cấm sử dụng bất kỳ hàm số mũ nào, nếu không v**(1/.3)sẽ là người chiến thắng chắc chắn.
primo

3

Javascript (55)

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

THƯỞNG, Công thức chung cho tất cả các rễ
function f(n,p){for(i=x=99;i--;)x=x-(x-n/Math.pow(x,p-1))/p;return x}

Đối với root cube, chỉ cần sử dụng f(n,3), căn bậc hai f(n,2), v.v ... Ví dụ: f(1024,10)return 2.

Giải thích
Dựa trên phương pháp Newton:

Tìm : f(x) = x^3 - n = 0, giải pháp là n = x^3
Đạo hàm:f'(x) = 3*x^2

Lặp lại:
x(i+1) = x(i) - f(x(i))/f'(x(i)) = x(i) + (2/3)*x + (1/3)*n/x^2

Xét nghiệm

[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) 

Một ký tự ngắn hơn:function f(n){for(i=x=99;i--;)x-=(x-n/x/x)/3;return x}
sao chép

Có thể giảm xuống 47 bytef=(n)=>eval('for(i=x=99;i--;)x=(2*x+n/x/x)/3')
Luis felipe De jesus Munoz

2

PHP - 81 byte

Giải pháp lặp lại:

$i=0;while(($y=abs($x=$argv[1]))-$i*$i*$i>1e-4)$i+=1e-5;@print $y/$x*round($i,4);

Điều gì xảy ra nếu nó cố gắng tính toán khối lập phương bằng không?
Victor Stafusa

Nó sẽ chỉ xuất "0" (nhờ toán tử triệt tiêu lỗi - "@").
Razvan

1
0.0001có thể được thay thế bởi 1e-40.00001bởi 1e.5.
ComFalet

Điều này đòi hỏi PHP <7 ( 0/0đưa ra NANtrong PHP 7). $i=0;là không cần thiết (-5 byte. Nếu không phải làt, forsẽ lưu một byte.) Không gian sau printkhông bắt buộc (-1 byte). -Rcó thể lưu 3 byte với $argn.
Tít

Lưu một cặp parantheses với while(1e-4+$i*$i*$i<$y=abs($x=$argn))(-2 byte).
Tít

2

Perl, 92 byte

sub a{$x=1;while($d=($x-$_[0]/$x/$x)/3,abs$d>1e-9){$x-=$d}$_=sprintf'%.4f',$x;s/\.?0*$//;$_}
  • Hàm atrả về một chuỗi với số không có phần phân số không cần thiết hoặc các số 0 không đáng kể ở đầu bên phải.

Kết quả:

              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

Được tạo bởi

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;

Tính toán dựa trên phương pháp của Newton :

Phép tính


2

APL - 31

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

Sử dụng thực tế rằng cbrt(x)=e^(ln(x)/3), nhưng thay vì thực hiện phép lũy thừa ngây thơ , nó tính toán e^xsử dụng chuỗi Taylor / Maclaurin.

Chạy mẫu:

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

Nhìn thấy có một câu trả lời J trong 16 ký tự, tôi phải thực sự khủng khiếp tại APL ...


2

Java, 207 182 181

Thỉnh thoảng khi tôi chơi gôn, tôi có hai bia và chơi rất tệ.

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

Phương pháp gần đúng của Newton, chạy 99 lần lặp.

Đây là 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 );
    }
}

1
Bạn có thể đổi tên argsbiến thành một cái gì đó như z, giảm 6 ký tự. Bạn có thể loại bỏ khoảng trắng và dấu ngoặc nhọn trong thân vòng lặp for, giảm 3 ký tự. Bạn có thể thay thế 10000.0bằng cách 1e4giảm 6 ký tự. Lớp học không cần phải công khai, vì vậy bạn có thể giảm thêm 7 ký tự. Bằng cách này, nó sẽ được giảm xuống 185 ký tự.
Victor Stafusa

Là diễn viên cuối cùng thực sự cần thiết? Nó không dành cho tôi.
Victor Stafusa

@Victor Cảm ơn vì mắt tốt, việc sử dụng ký hiệu E cho đôi 10000.0 là một ý tưởng tuyệt vời. Theo thiết kế của câu hỏi, tôi nghĩ việc biến nó thành một phương thức thay vì một lớp cli hoạt động là hợp pháp, điều này sẽ làm giảm đáng kể kích thước. Với Java, tôi đã không nghĩ rằng mình có cơ hội, vì vậy tôi đã nhầm lẫn về mặt chức năng.
md_rasler

Chào mừng đến với CodeGolf! Đừng quên thêm một lời giải thích trong câu trả lời về cách thức hoạt động của nó!
Justin

@Quincunx, Cảm ơn, đã đề nghị thay đổi.
md_rasler

2

TI-Basic, 26 24 byte

Input :1:For(I,1,9:2Ans/3+X/(3AnsAns:End

Điều đó trực tiếp sử dụng ^toán tử, không phải nó. Nó bị cấm theo các quy tắc
mniip

@mniip: Là e^một nhà điều hành duy nhất trên dòng TI-83? Tôi không nhớ. Dù bằng cách nào, nó vi phạm tinh thần của các quy tắc.
Ốc cơ khí

@M cơ học Tôi không quan trọng tôi sẽ nói. Trong hầu hết các ngôn ngữ bạn chỉ có thể làm exp(ln(x)/3)hoặc e^(ln(x/3))nếu bạn cho phép bất kỳ hai ngôn ngữ này. Nhưng bằng cách nào đó tôi hiểu exp(ln(x)/a)quá nhiều tương đương với x^(1/a)việc được cho phép bởi các quy tắc: - /
yo '

Hàm số mũ: "một hàm có giá trị là hằng số được nâng lên thành sức mạnh của đối số , đặc biệt là hàm có hằng số là e." ... "Không sử dụng các phương thức / toán tử có thể tăng số lên một sức mạnh"
mbomb007

Cảm ơn bạn đã bắt @ mbomb007, tôi đã viết câu trả lời này hơn 3 năm trước và tôi sẽ sửa nó để tuân thủ ngay bây giờ.
Timtech

2

Js 57 byte

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>


2

Javascript: 73/72 ký tự

Thuật toán này là khập khiễng và khai thác thực tế là câu hỏi này được giới hạn ở 4 chữ số sau dấu thập phân. Nó là một phiên bản sửa đổi của thuật toán mà tôi đề xuất trong hộp cát với mục đích làm lại câu hỏi. Nó đếm từ 0 đến vô hạn h*h*h<a, chỉ với một phép nhân và phép chia để xử lý 4 chữ số thập phân.

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

Chỉnh sửa, 4 năm sau: Theo đề xuất của Luis felipe De jesus Munoz, bằng cách sử dụng **mã ngắn hơn, nhưng tính năng đó không có sẵn vào năm 2014 khi tôi viết câu trả lời này. Dù sao, bằng cách sử dụng nó, chúng tôi cạo thêm một nhân vật:

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

1
Thay vào đó, h*h*hbạn có thể làm h**3và lưu 1 byte
Luis felipe De jesus Munoz

@LuisfelipeDejesusMunoz Câu trả lời này là từ năm 2014. Nhà **điều hành đã được đề xuất vào năm 2015 và được chấp nhận là một phần của ECMAScript 7 vào năm 2016. Vì vậy, tại thời điểm tôi viết rằng, không có **ngôn ngữ.
Victor Stafusa

1

Javascript - 157 ký tự

Chức năng này:

  • Xử lý số âm.
  • Xử lý các số chỉ nổi.
  • Thực hiện nhanh chóng cho bất kỳ số đầu vào.
  • Có độ chính xác tối đa được phép cho các số dấu phẩy động 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}

Phiên bản giải thích của Ungolfed:

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
}

1

PHP, 61

Dựa trên phương pháp của Newton. Phiên bản sửa đổi của câu trả lời của Michael :

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

Nó hoạt động với các số âm, có thể xử lý các số dấu phẩy động và làm tròn kết quả thành 4 số sau dấu thập phân nếu kết quả là số dấu phẩy động.

Bản demo làm việc


Bạn có thể lưu hai byte với for($x=1;++$i<100;).... Nhưng sử dụng các biến được xác định trước làm đầu vào thường được tán thành . Sử dụng tốt hơn $argv[1]hoặc $argn.
Tít

1

Befunge 98 - Công việc đang tiến triển

Ngôn ngữ này không hỗ trợ số dấu phẩy động; điều này cố gắng thi đua chúng. Hiện tại nó hoạt động cho các số dương không bắt đầu bằng 0dấu thập phân (phần lớn). Tuy nhiên, nó chỉ xuất ra 2 chữ số thập phân.

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

Nó hoạt động bằng cách nhập phần trước dấu thập phân, nhân số đó với 100000, sau đó nhập phần sau điểm và cộng hai số lại với nhau. Dòng thứ hai thực hiện một bộ đếm cho đến khi khối lập phương lớn hơn số được nhập. Sau đó, dòng thứ ba trích xuất số thập phân từ số nguyên.

Nếu bất cứ ai có thể cho tôi biết lý do tại sao dòng thứ ba chỉ chia 100cho các giá trị chính xác, xin vui lòng cho tôi biết.

IOs:

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

1

Smalltalk, 37

tín dụng đi đến mniip cho thuật toán; Phiên bản Smalltalk của mã của mình:

đầu vào trong n; đầu ra trong x:

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

hoặc, như một khối

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

1

Ngôn ngữ GameMaker, 51 byte

for(i=x=1;i++<99;1)x=(2*x+argument0/x/x)/3;return x

0

Haskell: 99C

Không thể đánh bại @mniip trong sự thông minh. Tôi vừa đi với một tìm kiếm nhị phân.

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

Ung dung:

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

Bạn có thể sử dụng toán tử infix cho d(như (l#h)x) để lưu một byte cho mỗi cuộc gọi. csau đó trở thành id>>=(0#).
Esolanging Fruit

Bạn có thể loại bỏ không gian xung quanh c < x.
Esolanging Fruit

Bạn có thể sử dụng 1>0thay vì True.
Esolanging Fruit

0

28 tháng 3

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

Sử dụng phương pháp Newton, tìm gốc của x^3 - Xbước cập nhật làx - (x^3 - C)/(3*x^2) , trong đó x là dự đoán hiện tại và C là đầu vào. Làm các phép toán trên cái này mang lại biểu thức đơn giản đến nực cười (2*x+C/x^2) /3. Chăm sóc phải được thực hiện cho các số âm.

Được thực hiện trong J, từ phải sang trái:

  1. | Bỏ qua cả hai đối số, vượt qua chúng
  2. ^:_ Làm cho đến khi hội tụ
  3. (%*~@])C / x^2( *~ ytương đương với y * y)
  4. +:@]2 x
  5. 3%~chia cho ba. Điều này mang lại gốc tích cực
  6. *@[ * positive_root nhân số gốc dương với dấu hiệu của C.

Chạy thử nghiệm:

   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

0

AWK, 53 byte

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

Ví dụ sử dụng:

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

Cảm ơn, hãy đến @Mig để biết JavaScriptgiải pháp này. Nó chạy nhanh một cách đáng ngạc nhiên khi forvòng lặp yêu cầu lặp lại để thay đổi.



0

Stax , 10 byte CP437

╘♀┘A╕äO¶∩'

Chạy và gỡ lỗi trực tuyến!

Giải trình

Sử dụng phiên bản giải nén để giải thích.

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

0

Giải pháp JAVA

công khai BigDecimal cubeRoot (số 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);
}

1
Chào mừng đến với PPCG! Đây là một môn đánh gôn thử thách , có nghĩa là mục tiêu là giải quyết thử thách càng ít mã càng tốt (tính bằng byte của tệp nguồn). Bạn nên thể hiện một số nỗ lực để tối ưu hóa giải pháp của mình cho mục tiêu đó và bao gồm số byte trong câu trả lời của bạn.
Martin Ender

0

Giải pháp 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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.