Xấp xỉ của tôi


10

Lấy cảm hứng từ video này bởi tecmath .

Một xấp xỉ của căn bậc hai của bất kỳ số nào xcó thể được tìm thấy bằng cách lấy căn bậc hai số nguyên s(nghĩa là số nguyên lớn nhất như vậy s * s ≤ x) và sau đó tính toán s + (x - s^2) / (2 * s). Hãy để chúng tôi gọi gần đúng này S(x). (Lưu ý: điều này tương đương với việc áp dụng một bước của phương pháp Newton-Raphson).

Mặc dù điều này không có gì khó hiểu, trong đó S (n ^ 2 - 1) sẽ luôn là √ (n ^ 2), nhưng nhìn chung nó sẽ rất chính xác. Trong một số trường hợp lớn hơn, điều này có thể có độ chính xác> 99,99%.

Đầu vào và đầu ra

Bạn sẽ lấy một số ở bất kỳ định dạng liên tục nào.

Ví dụ

Định dạng: Đầu vào -> Đầu ra

2 -> 1.50
5 -> 2.25
15 -> 4.00
19 -> 4.37               // actually 4.37       + 1/200
27 -> 5.20
39 -> 6.25
47 -> 6.91               // actually 6.91       + 1/300
57 -> 7.57               // actually 7.57       + 1/700
2612 -> 51.10            // actually 51.10      + 2/255
643545345 -> 25368.19    // actually 25,368.19  + 250,000,000/45,113,102,859
35235234236 -> 187710.50 // actually 187,710.50 + 500,000,000/77,374,278,481

Thông số kỹ thuật

  • Đầu ra của bạn phải được làm tròn đến ít nhất là một phần trăm gần nhất (nghĩa là nếu câu trả lời là 47.2851, bạn có thể xuất 47,29)

  • Đầu ra của bạn không cần phải có các số 0 và dấu thập phân nếu câu trả lời là một số nguyên (ví dụ: 125.00 cũng có thể được xuất ra là 125 và 125.0)

  • Bạn không phải hỗ trợ bất kỳ số nào dưới 1.

  • Bạn không phải hỗ trợ đầu vào không nguyên. (ví dụ: 1,52, v.v ...)

Quy tắc

Lỗ hổng tiêu chuẩn bị cấm.

Đây là một , vì vậy câu trả lời ngắn nhất bằng byte thắng.



3
Lưu ý:s + (x - s^2) / (2 * s) == (x + s^2) / (2 * s)
JungHwan Min

Giải pháp của tôi: Pyth , 25 byte ; 14 byte
Stan Strum

Có cần phải chính xác đến ít nhất 2 chữ số không?
hoàn toàn là

@totallyhuman Vâng. 47.2851 có thể được biểu thị là 47.28, nhưng không chính xác hơn.
Stan Strum

Câu trả lời:


2

Thạch ,  8  7 byte

-1 byte nhờ vào công thức toán học đơn giản hóa của Olivier Grégoire - xem câu trả lời Java của họ .

÷ƽ+ƽH

Hãy thử trực tuyến!

Làm sao?

÷ƽ+ƽH - Link: number, n
 ƽ     - integer square root of n  -> s
÷       - divide                    -> n / s
    ƽ  - integer square root of n  -> s
   +    - add                       -> n / s + s
      H - halve                     -> (n / s + s) / 2

7 byte: ÷ƽ+ƽHLần đầu tiên thử sử dụng Jelly nên tôi có thể sai. Tôi ước tôi biết làm thế nào để lưu trữ ƽ, mặc dù, để không lặp lại nó. Điều đó có thể tiết kiệm một byte khác.
Olivier Grégoire

Cảm ơn @ OlivierGrégoire! ƽɓ÷⁹+Hsẽ không tính toán lại số nguyên gốc, nhưng nó cũng 7. ɓbắt đầu một chuỗi dyadic mới với các đối số được hoán đổi và sau đó đề cập đến đối số đúng của chuỗi đó (tức là kết quả của ƽ). ƽɓ÷+⁹Hcũng sẽ làm việc ở đây
Jonathan Allan


4

Java (OpenJDK 8) , 32 byte

n->(n/(n=(int)Math.sqrt(n))+n)/2

Hãy thử trực tuyến!

Giải thích

Mã này tương đương với điều này:

double approx_sqrt(double x) {
  double s = (int)Math.sqrt(x);  // assign the root integer to s
  return (x / s + s) / 2
}

Các toán học đằng sau:

s + (x - s²) / (2 * s)  =  (2 * s² + x - s²) / (2 * s)
                        =  (x + s²) / (2 * s)
                        =  (x + s²) / s / 2
                        =  ((x + s²) / s) / 2
                        =  (x / s + s² / s) / 2
                        =  (x / s + s) / 2

Điều này dường như không xử lý thông số kỹ thuật: Đầu ra của bạn phải được làm tròn đến ít nhất là hàng trăm gần nhất
Ayb4btu

2
Chà, nó được làm tròn đến thấp hơn hàng trăm gần nhất, vì vậy nó hoàn toàn hợp lệ.
Olivier Grégoire

Ah, tôi hiểu rồi, sự hiểu lầm của tôi.
Ayb4btu

4

Python 2 , 47 ... 36 byte

-3 byte nhờ @JungHwanMin
-1 byte nhờ @HyperNeutrino
-2 byte nhờ @JonathanFrech
-3 byte nhờ @ OlivierGrégoire

def f(x):s=int(x**.5);print(x/s+s)/2

Hãy thử trực tuyến!


-2 byte: s+(x-s*s)/s/2to(x+s*s)/s/2
JungHwan Min

-2 byte sử dụng hàm
HyperNeutrino

@HyperNeutrino tôi chỉ nhận được -1 byte
OVS

Ôi xin lỗi, tôi đã vô tình xóa một ký tự sau khi kiểm tra và sau đó đếm các byte sau: P yeah chỉ -1
HyperNeutrino

Bạn có thể không bỏ qua +.0và thay thế /s/2bằng /2./s, tiết kiệm hai byte?
Jonathan Frech


3

R, 43 byte 29 byte

x=scan()
(x/(s=x^.5%/%1)+s)/2

Cảm ơn @Giuseppe về phương trình mới và trợ giúp chơi golf 12 byte với giải pháp chia số nguyên. Bằng cách hoán đổi chức năng gọi để quét, tôi đánh gôn thêm một vài byte.

Hãy thử trực tuyến!


1
35 byte ; tổng quát hơn, bạn có thể sử dụng trường "tiêu đề" của TIO và đặt a f <- để gán chức năng. Tuy nhiên, giải pháp tốt, hãy chắc chắn rằng bạn đã đọc Mẹo chơi golf trong R khi bạn có cơ hội!
Giuseppe



2

JavaScript (ES7), 22 byte

x=>(s=x**.5|0)/2+x/s/2

Chúng tôi không thực sự cần một biến trung gian, vì vậy điều này thực sự có thể được viết lại thành:

x=>x/(x=x**.5|0)/2+x/2

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


2

C, 34 byte

Cảm ơn @Olivier Grégoire!

s;
#define f(x)(x/(s=sqrt(x))+s)/2

Chỉ hoạt động với floatđầu vào.

Hãy thử trực tuyến!

C,  41   39  37 byte

s;
#define f(x).5/(s=sqrt(x))*(x+s*s)

Hãy thử trực tuyến!

C,  49   47   45  43 byte

s;float f(x){return.5/(s=sqrt(x))*(x+s*s);}

Hãy thử trực tuyến!


Cảm ơn @JungHwan Min đã lưu hai byte!


1
47 byte ; chỉnh sửa: Cảm ơn bạn, nhưng tín dụng @JungHwanMin đã tìm thấy điều đó.
Stan Strum



2

AWK , 47 44 38 byte

{s=int($1^.5);printf"%.2f",$1/2/s+s/2}

Hãy thử trực tuyến!

LƯU Ý: TIO like có thêm 2 byte \nđể làm cho đầu ra đẹp hơn. :)

Cảm giác như gian lận một chút khi sử dụng sqrt để tìm căn bậc hai, vì vậy đây là một phiên bản có thêm một vài byte không.

{for(;++s*s<=$1;);s--;printf("%.3f\n",s+($1-s*s)/(2*s))}

Hãy thử trực tuyến!


1
tốt, bạn có thể nói đây là AWKward. Tôi sẽ thể hiện ra ngoài. chỉnh sửa: ban đầu tôi đã lên kế hoạch cho câu hỏi để tránh sử dụng sqrt, nhưng có quá nhiều câu trả lời và tôi sẽ bị tra tấn nếu tôi thay đổi nó để ý tưởng ban đầu của tôi hoạt động.
Stan Strum

Chơi chữ 'AWK' rất vui :)
Robert Benson

thay vì sqrt($1)bạn có thể sử dụng$1^.5
Cabbie407

Cảm ơn @ Cabbie407 không biết tại sao tôi không nghĩ về điều đó.
Robert Benson

1
Không có gì. Một số điều khác: bạn không cần \nlấy đầu ra, printf trong awk không cần dấu ngoặc đơn và công thức có thể được rút ngắn s/2+$1/s/2, dẫn đến kết quả {s=int($1^.5);printf"%.2f",s/2+$1/s/2}. Xin lỗi nếu nhận xét này có vẻ thô lỗ.
Cabbie407

1

Vợt , 92 byte

Cảm ơn @JungHwan Min về mẹo trong phần bình luận

(λ(x)(let([s(integer-sqrt x)])(~r(exact->inexact(/(+ x(* s s))(* 2 s)))#:precision'(= 2))))

Hãy thử trực tuyến!

Ung dung

(define(fun x)
  (let ([square (integer-sqrt x)])
    (~r (exact->inexact (/ (+ x (* square square)) (* 2 square)))
        #:precision'(= 2))))

1

PowerShell , 54 byte

param($x)($x+($s=(1..$x|?{$_*$_-le$x})[-1])*$s)/(2*$s)

Hãy thử trực tuyến! hoặc Xác minh một số trường hợp thử nghiệm

Đưa đầu vào $xvà sau đó thực hiện chính xác những gì được yêu cầu. Phần |?tìm thấy số nguyên tối đa, khi bình phương, là yếu tố -lcơ bản so với eđầu vào $x, sau đó chúng tôi thực hiện các phép tính cần thiết. Đầu ra là ẩn.


Ồ Tôi chưa bao giờ có thể hiểu cách mọi người chơi golf trong Windows Powershell
Stan Strum

@StanStrum Bạn không đơn độc, lol. : D
admBorkBork

1

Husk , 9 byte

½Ṡ§+K/(⌊√

Hãy thử trực tuyến!

Vẫn còn một cái gì đó xấu xí trong câu trả lời này, nhưng tôi dường như không thể tìm thấy một giải pháp ngắn hơn.

Giải trình

Tôi đang thực hiện một bước của thuật toán Newton (điều này thực sự tương đương với bước được đề xuất trong câu hỏi này)

½Ṡ§+K/(⌊√
  §+K/       A function which takes two numbers s and x, and returns s+x/s
 Ṡ           Call this function with the input as second argument and
      (⌊√    the floor of the square-root of the input as first argument
½            Halve the final result

Tôi nghĩ rằng bạn muốn phân chia thực tế, thay vì÷
H.PWiz

@ H.PWiz rất tiếc, tôi làm, cảm ơn bạn. Đó là phần còn lại từ một thử nghiệm để tìm giải pháp khác
Leo

1

Pyt , 11 10 byte

←Đ√⌊Đ↔⇹/+₂

Giải trình

code                explanation                        stack
←                   get input                          [input]
 Đ                  duplicate ToS                      [input,input]
  √⌊                calculate s                        [input,s]
    Đ               duplicate ToS                      [input,s,s]
     ↔              reverse stack                      [s,s,input]
      ⇹             swap ToS and SoS                   [s,input,s]
       /            divide                             [s,input/s]
        +           add                                [s+input/s]
         ₂          halve                              [(s+input/s)/2]
                    implicit print

Chỉ cần nhìn thấy điều này và đó là một phút tốt cho đến khi tôi nhận ra nó không phải là Pyth. Câu trả lời chính xác.
Stan Strum

Vâng, đó là một ngôn ngữ nhỏ mà tôi đã suy nghĩ một lúc và quyết định thực sự làm.
Mudkip201

Là ToS hàng đầu ... và nếu vậy, SoS là gì?
Stan Strum

ToS đứng đầu stack và SoS đứng thứ hai trên stack
Mudkip201

Thật tuyệt, tôi sẽ xem liệu tôi có thể đi sâu vào ngôn ngữ này không; Tôi thích nó!
Stan Strum

1

Dải ngân hà , 17 14 byte

-3 byte bằng cách sử dụng công thức của Olivier Grégoire

^^':2;g:>/+2/!

Hãy thử trực tuyến!

Giải trình

code              explanation                   stack layout

^^                clear preinitialized stack    []
  ':              push input and duplicate it   [input, input]
    2;            push 2 and swap ToS and SoS   [input, 2, input]
      g           nth root                      [input, s=floor(sqrt(input))]
       :          duplicate ToS                 [input, s, s]
        >         rotate stack right            [s, input, s]
         /        divide                        [s, input/s]
          +       add                           [s+input/s]
           2/     divide by 2                   [(s+input/s)/2]
             !    output                        => (s+input/s)/2

không nên là sàn thay vì trần?
Mudkip201

@ Mudkip201 Cập nhật, cảm ơn
ovs

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.