กำลังสองของฉันโดยประมาณ


10

แรงบันดาลใจจากวิดีโอนี้โดย tecmath

ประมาณของรากที่สองของจำนวนใด ๆ ที่xสามารถพบได้โดยการจำนวนเต็มรากs(เช่นที่ใหญ่ที่สุดจำนวนเต็มเช่นนั้นs * s ≤ x) s + (x - s^2) / (2 * s)และจากนั้นการคำนวณ ให้เราเรียกการประมาณนี้S(x)ว่า (หมายเหตุ: นี่เทียบเท่ากับการใช้ขั้นตอนเดียวของวิธีการ Newton-Raphson)

แม้ว่านี่จะมีมุมแหลมที่ S (n ^ 2 - 1) จะเป็น√ (n ^ 2) เสมอ แต่โดยทั่วไปมันจะแม่นยำมาก ในบางกรณีที่มีขนาดใหญ่กว่านี้อาจมีความแม่นยำมากกว่า 99.99%

อินพุตและเอาต์พุต

คุณจะใช้หมายเลขหนึ่งในรูปแบบ Convienent ใด ๆ

ตัวอย่าง

รูปแบบ: อินพุต -> เอาท์พุท

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

ข้อมูลจำเพาะ

  • ผลลัพธ์ของคุณจะต้องถูกปัดเศษเป็นอย่างน้อยหนึ่งร้อยที่ใกล้ที่สุด (เช่นถ้าคำตอบคือ 47.2851 คุณอาจส่งออก 47.29)

  • ผลลัพธ์ของคุณไม่จำเป็นต้องมีค่าศูนย์ดังต่อไปนี้และจุดทศนิยมหากคำตอบคือจำนวนเต็ม (เช่น 125.00 สามารถแสดงผลเป็น 125 และ 125.0 ได้เช่นกัน)

  • คุณไม่จำเป็นต้องสนับสนุนหมายเลขใด ๆ ด้านล่าง 1

  • คุณไม่จำเป็นต้องรองรับอินพุตที่ไม่ใช่จำนวนเต็ม (เช่น 1.52 ฯลฯ ... )

กฎระเบียบ

ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม

นี่คือดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ



3
หมายเหตุ:s + (x - s^2) / (2 * s) == (x + s^2) / (2 * s)
JungHwan Min

โซลูชันของฉัน: Pyth , 25 ไบต์ ; 14 ไบต์
Stan Strum

จำเป็นต้องแม่นยำอย่างน้อย 2 หลักหรือไม่
สิ้นเชิงมนุษย์

@tallyallyhuman ใช่ 47.2851 สามารถแสดงเป็น 47.28 แต่ไม่ถูกต้องอีกต่อไป
Stan Strum

คำตอบ:


2

เยลลี่ ,  8  7 ไบต์

-1 ขอบคุณไบต์โอลิเวียGrégoireของสูตรทางคณิตศาสตร์ที่เรียบง่าย - ดูพวกเขาตอบ Java

÷ƽ+ƽH

ลองออนไลน์!

อย่างไร?

÷ƽ+ƽ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 ไบต์: ÷ƽ+ƽHครั้งแรกที่พยายามใช้ Jelly ดังนั้นฉันอาจผิด ฉันหวังว่าฉันจะรู้วิธีการเก็บƽแม้ว่าจะไม่ทำซ้ำ นั่นอาจช่วยประหยัดไบต์อื่นได้
Olivier Grégoire

ขอบคุณ @ OlivierGrégoire! ƽɓ÷⁹+Hจะไม่คำนวณรากจำนวนเต็มอีกครั้ง แต่ยังคำนวณจุดɓเริ่มต้นของโซ่ dyadic ใหม่ด้วยอาร์กิวเมนต์ที่สลับเปลี่ยนจากนั้นอ้างถึงอาร์กิวเมนต์ที่ถูกต้องของโซ่นั้น (เช่นผลลัพธ์ของƽ) ƽɓ÷+⁹Hจะทำงานที่นี่ด้วย
Jonathan Allan


4

Java (OpenJDK 8) , 32 ไบต์

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

ลองออนไลน์!

คำอธิบาย

รหัสเทียบเท่ากับสิ่งนี้:

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

คณิตศาสตร์ที่อยู่เบื้องหลัง:

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

สิ่งนี้ดูเหมือนจะไม่จัดการกับข้อมูลจำเพาะ: ผลลัพธ์ของคุณจะต้องถูกปัดเศษเป็นอย่างน้อยร้อยที่ใกล้ที่สุด
Ayb4btu

2
มันถูกปัดเศษให้ต่ำกว่าร้อยที่ใกล้ที่สุดดังนั้นมันจึงใช้ได้จริง
Olivier Grégoire

ฉันเข้าใจแล้วฉันเข้าใจผิด
Ayb4btu

4

Python 2 , 47 ... 36 ไบต์

-3 ไบต์ขอบคุณ @JungHwanMin
-1 ไบต์ขอบคุณ @HyperNeutrino
-2 ไบต์ขอบคุณ@JonathanFrech
-3 ไบต์ขอบคุณ @ OlivierGrégoire

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

ลองออนไลน์!


-2 ไบต์: s+(x-s*s)/s/2ถึง(x+s*s)/s/2
JungHwan Min

-2 ไบต์โดยใช้ฟังก์ชั่น
HyperNeutrino

@HyperNeutrino ฉันได้รับเพียง-1 ไบต์
ovs

โอ้ขอโทษฉันลบตัวละครโดยบังเอิญหลังจากการทดสอบแล้วนับจำนวนไบต์หลัง: P ใช่เพียง -1
HyperNeutrino

คุณไม่สามารถละเว้น+.0และแทนที่/s/2ด้วย/2./sการบันทึกสองไบต์ได้หรือไม่
Jonathan Frech


3

R, 43 ไบต์ 29 ไบต์

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

ขอบคุณ @Giuseppe สำหรับสมการใหม่และช่วยในการเล่นกอล์ฟขนาด 12 ไบต์ด้วยโซลูชั่นการหารจำนวนเต็ม โดยการสลับการเรียกฟังก์ชันเพื่อสแกนฉันเล่นกอล์ฟอีกสองไบต์

ลองออนไลน์!


1
35 ไบต์ ; โดยทั่วไปคุณสามารถใช้ฟิลด์ "ส่วนหัว" ของ TIO และใส่f <- เพื่อกำหนดฟังก์ชั่น แต่ก็ยังเป็นทางออกที่ดีให้แน่ใจว่าคุณอ่านเคล็ดลับสำหรับการเล่นกอล์ฟใน Rเมื่อคุณมีโอกาส!
Giuseppe



2

JavaScript (ES7), 22 ไบต์

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

เราไม่ต้องการตัวแปรกลางดังนั้นนี่จึงสามารถเขียนใหม่เป็น:

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

กรณีทดสอบ


2

C, 34 ไบต์

ขอบคุณ @Olivier Grégoire!

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

ทำงานได้กับfloatอินพุตเท่านั้น

ลองออนไลน์!

C,  41   39  37 ไบต์

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

ลองออนไลน์!

C,  49   47   45  43 ไบต์

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

ลองออนไลน์!


ขอบคุณ @JungHwan Min สำหรับการบันทึกสองไบต์!


1
47 ไบต์ ; แก้ไข: ขอบคุณ แต่ให้เครดิต @JungHwanMin ในการค้นหาสิ่งนั้น
Stan Strum



2

AWK , 47 44 38 ไบต์

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

ลองออนไลน์!

หมายเหตุ: TIO ที่ชอบมี 2 ไบต์พิเศษสำหรับ\nการทำให้เอาต์พุตสวย :)

รู้สึกเหมือนโกงนิดหน่อยที่จะใช้ sqrt เพื่อค้นหาสแควร์รูทดังนั้นนี่เป็นรุ่นที่มีจำนวนไบต์ไม่มากนัก

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

ลองออนไลน์!


1
คุณสามารถพูดได้ว่านี่คือ AWKward ฉันจะแสดงตัวเองออกมา แก้ไข: เดิมฉันวางแผนไว้สำหรับคำถามที่จะหลีกเลี่ยงการใช้ sqrt แต่มีคำตอบมากมายและฉันจะถูกละเมิดถ้าฉันเปลี่ยนมันเพื่อให้ความคิดดั้งเดิมของฉันทำงาน
Stan Strum

การเล่น 'AWK' นั้นสนุก :)
Robert Benson

แทนที่จะเป็นsqrt($1)คุณสามารถใช้$1^.5
Cabbie407

ขอบคุณ @ Cabbie407 ไม่รู้ว่าทำไมฉันไม่คิดอย่างนั้น
Robert Benson

1
ไม่เป็นไร บางสิ่งอื่น ๆ : คุณไม่จำเป็นต้อง\nที่จะได้รับการส่งออกใน printf awk ไม่จำเป็นต้องวงเล็บและสูตรที่สามารถลงไปซึ่งผลในการs/2+$1/s/2 {s=int($1^.5);printf"%.2f",s/2+$1/s/2}ขออภัยถ้าความคิดเห็นนี้ดูหยาบคาย
Cabbie407


1

PowerShellขนาด 54 ไบต์

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

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบบางอย่าง

รับอินพุต$xจากนั้นทำตามที่ร้องขอ |?ส่วนหนึ่งพบสูงสุดจำนวนเต็มว่าเมื่อยกกำลังสองเป็น-lESS กว่า or- equal เพื่อป้อนข้อมูล$xแล้วเราดำเนินการคำนวณที่จำเป็น เอาท์พุทเป็นนัย


ว้าว. ฉันไม่เคยเข้าใจว่าผู้คนเล่นกอล์ฟใน Windows Powershell ได้อย่างไร
Stan Strum

@StanStrum คุณไม่ได้อยู่คนเดียว lol : D
AdmBorkBork

1

Husk , 9 ไบต์

½Ṡ§+K/(⌊√

ลองออนไลน์!

ยังมีบางสิ่งที่น่าเกลียดในคำตอบนี้ แต่ฉันไม่สามารถหาวิธีแก้ปัญหาที่สั้นกว่านี้ได้

คำอธิบาย

ฉันกำลังใช้อัลกอริทึมของขั้นตอนหนึ่งของนิวตัน (ซึ่งแน่นอนเทียบเท่ากับที่เสนอในคำถามนี้)

½Ṡ§+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

ฉันคิดว่าคุณต้องการการแบ่งที่แท้จริงมากกว่า÷
H.PWiz

@ H.PWiz อ๊ะฉันทำขอบคุณ นั่นคือส่วนที่เหลือจากการทดลองเพื่อค้นหาวิธีแก้ปัญหาอื่น ๆ
Leo

1

Pyt , 11 10 ไบต์

←Đ√⌊Đ↔⇹/+₂

คำอธิบาย

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

เพิ่งเห็นสิ่งนี้และมันเป็นนาทีที่ดีจนกระทั่งฉันรู้ว่ามันไม่ใช่ Pyth คำตอบที่ดี
Stan Strum

ใช่มันเป็นภาษาเล็ก ๆ น้อย ๆ ที่ฉันคิดอยู่พักหนึ่งแล้วก็ตัดสินใจทำจริงๆ
mudkip201

ToS อยู่ด้านบนสุดของสแต็ค ... และถ้าเป็นเช่นนั้น SoS คืออะไร
Stan Strum

ToS อยู่ด้านบนสุดของสแต็กและ SoS เป็นที่สองใน stack
mudkip201

ดีฉันจะดูว่าฉันสามารถขุดเป็นภาษานี้ ฉันชอบมัน!
Stan Strum

1

ทางช้างเผือก , 17 14 ไบต์

-3 ไบต์โดยใช้สูตรของ Olivier Grégoire

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

ลองออนไลน์!

คำอธิบาย

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

ไม่ควรที่จะเป็นพื้นแทนที่จะเป็นเพดาน?
mudkip201

@ mudkip201 อัปเดตขอบคุณ
ovs

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.