คำนวณค่าเฉลี่ยของตัวเลขสองตัว


41

ข้อจำกัดความรับผิดชอบ: ค่าเฉลี่ยฉันถูกสร้างขึ้น

กำหนดค่าเฉลี่ยเลขคณิตของตัวเลขเป็น กำหนดค่าเฉลี่ยทางเรขาคณิตของตัวเลขnเป็น M_0 (x_1, ... , x_n) = \ root {n} \ of {x_1x_2 ... x_n} กำหนดค่าเฉลี่ยฮาร์มอนิกของตัวเลขnเป็น M _ {- 1} (x_1, ... , x_n) = \ frac {n} {\ frac {1 } {x_2} + \ frac {1} {x_2} + ... + \ frac {1} {x_n}} กำหนดค่าเฉลี่ยกำลังสองของจำนวนnเป็น M_2 (x_1, ... , x_n) = \ root \ of {\ frac {x_1 ^ 2 + x_2 ^ 2 + ... + x_n ^ 2} {n}} หมายถึงค่าเฉลี่ย ( M_M ) ถูกกำหนดดังนี้: กำหนดสี่ลำดับ ( a_k, b_k, c_k, d_k ) เป็นn

M1(x1,...,xn)=x1+x2+...+xnn
n
M0(x1,...,xn)=x1x2...xnn
n
M1(x1,...,xn)=n1x2+1x2+...+1xn
n
M2(x1,...,xn)=x12+x22+...+xn2n
MMak,bk,ck,dk
a0=M1(x1,...,xn),b0=M0(x1,...,xn),c0=M1(x1,...,xn),d0=M2(x1,...,xn),ak+1=M1(ak,bk,ck,dk),bk+1=M0(ak,bk,ck,dk),ck+1=M1(ak,bk,ck,dk),dk+1=M2(ak,bk,ck,dk)
ทั้งสี่ลำดับมาบรรจบกัน จำนวนเดียวกันMM(x1,x2,...,xn)x_n)

ตัวอย่าง

คำนวณค่าเฉลี่ยค่าเฉลี่ยของ 1 และ 2 ดังนี้เริ่มต้นด้วย

a0=(1+2)/2=1.5,b0=12=21.4142,c0=211+12=431.3333,d0=12+222=521.5811.
จากนั้น
a1=1.5+1.4142+1.3333+1.581141.4571,b1=1.51.41421.33331.581141.4542,c1=411.5+11.4142+11.3333+11.58111.4512,d1=1.52+1.41422+1.33332+1.5811241.4601.
การคำนวณลำดับเพิ่มเติมควรมีความชัดเจน จะเห็นได้ว่าพวกเขาจะมาบรรจบหมายเลขเดียวกันประมาณ1.455688891.45568889

ท้าทาย

ได้รับสองจำนวนจริงบวกและ ( <b ) การคำนวณของพวกเขาหมายถึงค่าเฉลี่ยM_M (A, B)aba<bMM(a,b)

กรณีทดสอบ

1 1 => 1
1 2 => 1.45568889
100 200 => 145.568889
2.71 3.14 => 2.92103713
0.57 1.78 => 1.0848205
1.61 2.41 => 1.98965438
0.01 100 => 6.7483058

หมายเหตุ

  • โปรแกรมของคุณถูกต้องหากความแตกต่างระหว่างเอาต์พุตและเอาต์พุตที่ถูกต้องไม่เกิน 1/100000 ของค่าสัมบูรณ์ของความแตกต่างระหว่างหมายเลขอินพุท
  • ผลลัพธ์ควรเป็นตัวเลขเดียว

นี่คือดังนั้นรหัสที่สั้นที่สุดชนะ!




11
เราควรจะแม่นยำแค่ไหน?
ศูนย์รวมแห่งความไม่รู้


1
เราสามารถสมมติว่าอินพุตแรกเล็กกว่าครั้งที่สองเสมอในทุกกรณีทดสอบของคุณหรือไม่? (ถ้าไม่ใช่ฉันจะย้อนคำตอบ Java ของฉัน)
Kevin Cruijssen

คำตอบ:


14

ภาษา Wolfram (Mathematica) , 52 ไบต์

#//.x_:>N@{M@x,E^M@Log@x,1/M[1/x],M[x^2]^.5}&
M=Mean

ลองออนไลน์!

ในวิธีแรกของฉันฉันใช้ builtins เหล่านี้
Mean GeometricMean HarmonicMeanและRootMeanSquare

นี่คือการทดแทนบางส่วนสำหรับการบันทึกไบต์

HarmonicMean-> 1/Mean[1/x] โดย @Robin Ryder (บันทึกแล้ว 3 ไบต์)
GeometricMean-> E^Mean@Log@xโดย @A Rex (บันทึก 2 ไบต์)
RootMeanSquare-> Mean[x^2]^.5โดย @A เร็กซ์ (บันทึก 4 ไบต์)

ในที่สุดเราสามารถมอบหมายMeanให้M(ตามที่เสนอโดย @ovs) และบันทึกอีก 5 ไบต์


บันทึก 2 ไบต์ด้วยการเข้ารหัส GeometricMean
Robin Ryder

@RobinRyder ฉันเชื่อว่าคุณหมายถึง Harmonic .. nice!
J42161217

1
บันทึก 8 ไบต์เพิ่มเติม :#//.x_:>N@{Mean@x,E^Mean@Log@x,1/Mean[1/x],Mean[x^2]^.5}&
A. Rex

@ovs แก้ไข .....
J42161217

10

R, 70 69 67 ไบต์

x=scan();`?`=mean;while(x-?x)x=c((?x^2)^.5,?x,2^?log2(x),1/?1/x);?x

ลองออนไลน์!

-1 ไบต์พร้อมการปรับสภาพที่ดีขึ้น
-2 ไบต์โดยสลับไปที่ฐาน 2

เช่นเดียวกับคำตอบอื่น ๆ นี่ใช้การแสดงออกของค่าเฉลี่ยเรขาคณิตเป็นค่าเฉลี่ยเลขคณิตในระดับบันทึก (ที่นี่ในฐาน 2):

M0(x1,,xn)=2M1(log2x1,,log2xn).

นอกจากนี้ยังใช้ในความเป็นจริงว่าคือd_k) เงื่อนไขดังนั้นจึงเท่ากับซึ่งเป็นสิ่งที่ฉันใช้ในขณะที่ลูป; นี่คือความสำเร็จโดยการใช้ไวยากรณ์ที่พิจารณาองค์ประกอบแรกเมื่อเงื่อนไขเป็นเวกเตอร์ดังนั้นลำดับที่เก็บหมายถึง (โปรดทราบว่าเราสามารถใช้แทนได้เนื่องจากมันเป็นค่าต่ำสุดของสี่ แต่เราไม่สามารถใช้หรือในสภาพได้)k,dkakbkckdk=max(ak,bk,ck,dk)ak=bk=ck=dkdk=M1(ak,bk,ck,dk)whileckakbk

เมื่อเราออกจากห่วงขณะที่xเป็นเวกเตอร์คงที่ ขั้นสุดท้าย?xคำนวณค่าเฉลี่ยเพื่อลดค่าสเกลาร์


1
ไม่ควรเป็นแทนที่จะเป็น ? lnxnlogxn
เอกภาพ

@ ใช่ฉันกำลังแสดงลอการิทึมธรรมชาติโดยซึ่งเป็นค่าเริ่มต้นใน R. อย่างไรก็ตามตอนนี้ฉันได้เปลี่ยนเป็นลอการิทึมฐาน 2 สำหรับ -2 ไบต์ log
Robin Ryder

6

J , 34 ไบต์

(31 เป็นนิพจน์ที่ไม่มีการกำหนดให้กับตัวแปรf)

f=:1{(^.z,%z,*:z,[z=:(+/%#)&.:)^:_

ลองออนไลน์!

สำหรับฟังก์ชั่นaและb, a &.: b("a ภายใต้ b" ( ความท้าทายที่เกี่ยวข้อง )) เทียบเท่ากับ(b inv) a b- ใช้ b, จากนั้น a, จากนั้นกลับกันของ b ในกรณีนี้ค่าเฉลี่ยเรขาคณิต / ฮาร์โมนิก / สมการกำลังสองคือค่าเฉลี่ยเลขคณิต "ภายใต้" ลอการิทึมการผกผันและกำลังสองตามลำดับ


5

TI-BASIC, 42 35 34 ไบต์

-1 ไบต์ขอบคุณ @SolomonUcko

While max(ΔList(Ans:{mean(Ans),√(mean(Ans²)),mean(Ans^-1)^-1,e^(mean(ln(Ans:End:Ans(1

Ansการป้อนข้อมูลเป็นรายการของจำนวนเต็มสองจำนวนใน
เอาต์พุตถูกเก็บไว้ในAnsและพิมพ์ออกมาโดยอัตโนมัติเมื่อโปรแกรมเสร็จสิ้น

สูตรที่ใช้สำหรับเรขาคณิตฮาร์โมนิและกำลังสองวิธีที่จะตามออกของคำอธิบายของ user202729

ตัวอย่าง:

{1,2
           {1 2}
prgmCDGFB
     1.455688891
{100,200
       {100 200}
prgmCDGFB
     145.5688891

คำอธิบาย:
(มีการเพิ่มบรรทัดใหม่สำหรับการชี้แจงซึ่งจะไม่ปรากฏในรหัส)

While max(ΔList(Ans           ;loop until all elements of the current list are equal
                              ; the maximum of the change in each element will be 0
{                             ;create a list containing...
 mean(Ans),                   ; the arithmetic mean
 √(mean(Ans²)),               ; the quadratic mean
 mean(Ans^-1)^-1,             ; the harmonic mean
 e^(mean(ln(Ans               ; and the geometric mean
End
Ans(1                         ;keep the first element in "Ans" and implicitly print it

หมายเหตุ:

TI-BASIC เป็นภาษาโทเค็น จำนวนตัวอักษรไม่เท่ากับจำนวนไบต์

e^(คือนี้โทเค็นหนึ่งไบต์

^-1จะใช้สำหรับการนี้โทเค็นหนึ่งไบต์
ฉันเลือกที่จะเขียน^-1แทนเพราะโทเค็นจะดูเหมือนֿ¹เมื่ออยู่ในบล็อคโค้ด

√(คือนี้โทเค็นหนึ่งไบต์

ΔList(คือนี้โทเค็นสองไบต์


ฉันคิดว่าคุณสามารถบันทึกวงเล็บได้โดยใส่ค่าเฉลี่ยเรขาคณิตไว้
โซโลมอน Ucko

@SolomonUcko อ่าขอบคุณที่สังเกต! ไม่เคยคิดมาก่อน
เอกภาพ

max(DeltaList(Ansvariance(Ans->
lirtosiast

5

Java 10, 234 229 214 211 215 206 203 196 180 177 ไบต์

a->{for(;a[1]-a[0]>4e-9;){double l=a.length,A[]={0,0,0,1};for(var d:a){A[2]+=d/l;A[3]*=Math.pow(d,1/l);A[0]+=1/d;A[1]+=d*d;}A[0]=l/A[0];A[1]=Math.sqrt(A[1]/l);a=A;}return a[0];}

-5 ไบต์ขอบคุณที่@PeterCordes
-15 เพิ่มเติมไบต์ขอบคุณที่@PeterCordesแรงบันดาลใจจาก@RobinRyder R คำตอบ
+4 ไบต์เพราะฉันคิดว่าอินพุตสั่งล่วงหน้า
-27 ไบต์ขอบคุณที่@ OlivierGrégoire

ลองออนไลน์

คำอธิบาย:

a->{                        // Method with double-array parameter and double return-type
  for(;a[1]-a[0]            //  Loop as long as the difference between the 2nd and 1st items
                >4e-9;){    //  is larger than 0.000000004:
    double l=a.length,      //   Set `l` to the amount of values in the array `a`
           A[]={0,0,0,1};   //   Create an array `A`, filled with the values [0,0,0,1]
    for(var d:a){           //   Inner loop over the values of `a`:
      A[2]+=d/l;            //    Calculate the sum divided by the length in the third spot
      A[3]*=Math.pow(d,1/l);//    The product of the power of 1/length in the fourth spot
      A[0]+=1/d;            //    The sum of 1/value in the first spot
      A[1]+=d*d;            //    And the sum of squares in the second spot
    }                       //   After the inner loop:
                            //   (the third spot of the array now holds the Arithmetic Mean)
                            //   (the fourth spot of the array now holds the Geometric Mean)
    A[0]=l/A[0];            //   Divide the length by the first spot
                            //   (this first spot of the array now holds the Harmonic Mean)
    A[1]=Math.sqrt(A[1]/l); //   Take the square of the second spot divided by the length
                            //   (this second spot of the array now holds the Quadratic Mean)
    a=A;                    //   And then replace input `a` with array `A`
  }                         //  After the outer loop when all values are approximately equal:
  return a[0];}             //  Return the value in the first spot as result

ใน C คุณสามารถf+=Math.abs(d-D)<1e-9;และได้รับการแปลงโดยปริยายจากผลการเปรียบเทียบกับบูล 0/1 doubleจำนวนเต็มแล้ว Java มีไวยากรณ์ขนาดกะทัดรัดหรือไม่ หรือเป็นไปได้ที่จะทำf+=Math.abs(d-D)แล้วตรวจสอบว่าผลรวมของความแตกต่างสัมบูรณ์มีขนาดเล็กเพียงพอหรือไม่
Peter Cordes

1
ใช่สำหรับกรณีทดสอบของคุณf>1e-8ทำงานเป็นเงื่อนไขลูป: 229 ไบต์ a->{for(double f=1,D,A[],l;f>1e-8;a=A){D=a[0];A=new double[]{f=0,1,0,0};for(var d:a){f+=Math.abs(d-D);A[0]+=d;A[1]*=d;A[2]+=1/d;A[3]+=d*d;}A[0]/=l=a.length;A[1]=Math.pow(A[1],1/l);A[2]=l/A[2];A[3]=Math.sqrt(A[3]/l);}return a[0];}. ด้วย1e-9มันจะทำงานช้าลง (ประมาณสองเท่าของเวลา CPU) โดยต้องทำซ้ำมากกว่าเดิมเพื่อให้ได้d-Dขนาดเล็กลง4 * ด้วย1e-7ความเร็วใกล้เคียงกับ 1e-8 ด้วย1e-6บางส่วนของตัวเลขต่อท้ายที่แตกต่างกันสำหรับกรณีหนึ่ง
Peter Cordes

1
@ คำตอบของ RobinRyder ชี้ให้เห็นว่าค่าเฉลี่ยกำลังสองเป็นค่าที่ใหญ่ที่สุดเสมอและค่าฮาร์มอนิกจะเล็กที่สุดเสมอดังนั้นบางทีคุณสามารถทิ้งทุกfอย่างa[3]-a[2]<4e-9ได้
Peter Cordes

1
@PeterCordes l==2||คุณหมายถึง ( golfed to l<3|) แต่ใช่จุดดี; ฉันได้เพิ่มมัน :)
Kevin Cruijssen

2
180 ไบต์โดยการรวมตัวลดที่รวมได้
Olivier Grégoire

3

ถ่าน 40 ไบต์

W‹⌊θ⌈θ≔⟦∕ΣθLθXΠθ∕¹Lθ∕LθΣ∕¹θ₂∕ΣXθ²Lθ⟧θI⊟θ

ลองออนไลน์! การเชื่อมโยงคือการใช้รหัสเวอร์ชันอย่างละเอียด รับอินพุตเป็นอาร์เรย์ของตัวเลข คำอธิบาย:

W‹⌊θ⌈θ

ทำซ้ำในขณะที่อาร์เรย์มีค่าต่างกัน ...

≔⟦....⟧θ

... แทนที่อาร์เรย์ด้วยรายการค่า:

∕ΣθLθ

... ความหมาย...

XΠθ∕¹Lθ

... ความหมายทางเรขาคณิต ...

∕LθΣ∕¹θ

... ค่าเฉลี่ยของฮาร์มอนิก ...

₂∕ΣXθ²Lθ

... และรูทหมายความว่ากำลังสอง

I⊟θ

ส่งองค์ประกอบของอาร์เรย์ไปยังสตริงและพิมพ์โดยนัย




3

05AB1E , 26 24 23 ไบต์

Δ©ÅA®.²ÅAo®zÅAz®nÅAt)}н

ลองมันออนไลน์หรือดูขั้นตอนของกรณีทดสอบทั้งหมด

-1 ขอบคุณไบต์@Grimy

23 byter ทางเลือกสำหรับค่าเฉลี่ยเรขาคณิต:

Δ©P®gzm®ÅA®zÅAz®nÅAt)}н

ลองมันออนไลน์หรือดูขั้นตอนของกรณีทดสอบทั้งหมด

คำอธิบาย:

Δ         # Loop until the list no longer changes:
 ©        #  Store the current list in variable `®` (without popping)
          #  (which is the implicit input-list in the first iteration)
          #  Arithmetic mean:
  ÅA      #   Builtin to calculate the arithmetic mean of the list
          #  Geometric mean:
  ®.²     #   Take the base-2 logarithm of each value in the list `®`
     ÅA   #   Get the arithmetic mean of that list
       o  #   And take 2 to the power of this mean
          #  Harmonic mean:
  ®z      #   Get 1/x for each value x in the list `®`
    ÅA    #   Get the arithmetic mean of that list
      z   #   And calculate 1/y for this mean y
          #  Quadratic mean:
  ®n      #   Take the square of each number x in the list from the register
    ÅA    #   Calculate the arithmetic mean of this list
      t   #   And take the square-root of that mean
  )       #  Wrap all four results into a list
        # After the list no longer changes: pop and push its first value
          # (which is output implicitly as result)

23:Δ©P®gzm®ÅA®zÅAz®nÅAt)}н
Grimmy

@Grimy ขอบคุณ! ไม่อยากจะเชื่อเลยว่าฉันไม่ได้คิดถึงการใช้ความยาวแทนที่จะYเป็น 2/4 :)
Kevin Cruijssen

1
อีก 23 ที่ betters แสดงให้เห็นความคล้ายคลึงกันของค่าเฉลี่ยเรขาคณิตกับคนอื่น ๆΔ©ÅA®.²ÅAo®zÅAz®nÅAt)}н: น่าเสียดายที่เราไม่สามารถปรับโครงสร้างเหล่านั้นÅAได้อีก
Grimmy

@Grimy โอ้ฉันชอบรุ่นที่สองนี้ :) แก้ไข: โอ๊ะโอขอบคุณที่สังเกตเห็นความผิดพลาดในคำอธิบาย .. >.>
Kevin Cruijssen

ฉันไม่ได้เขียนโปรแกรมใน 05ab1e เป็นอย่างดี แต่คุณสามารถคำนวณผลรวมแล้วหารพวกมันทั้งหมดในภายหลังได้หรือไม่
ใครบางคน

2

เยลลี่ , 25 24 ไบต์

Wẋ4¹ÆlÆeƭ²½ƭİ4ƭÆm$€⁺µÐLḢ

ลองออนไลน์!

คำอธิบาย

                    µÐL | Repeat until unchanged:
W                       |   Wrap as a list
 ẋ4                     |   Copy list 4 times
                   ⁺    |   Do twice:
                 $€     |     For each copy of the list:
             4ƭ         |     One of these functions, cycling between them:
   ¹                    |       Identity
    ÆlÆeƭ               |       Alternate between log and exp
         ²½ƭ            |       Alternate between square and square root
            İ           |       Reciprocal
               Æm       |    Then take the mean
                       Ḣ| Finally take the first item

ฉันค่อนข้างแย่ที่เยลลี่ แต่สิ่งที่คล้ายกับการP*İLทำงานเพื่อความหมายทางเรขาคณิต?
ใครบางคน

@ คนที่จะต้องเป็นP*Lİ$เช่นนั้นจะไม่บันทึกไบต์ มันหมายความว่าฉันสามารถนำÆmกลับมาลงบรรทัดโดยไม่คิดต้นทุนไบต์ แต่ฉันค่อนข้างชอบความจริงที่แต่ละคนมีค่าเฉลี่ยเลขคณิตที่แกนกลางของมัน
Nick Kennedy

2

Python 3 , 152 ไบต์

from math import*
s=sum
def f(*a):l=len(a);return 2>len({*a})and{*a}or f(s(a)/l,l/s(map(pow,a,l*[-1])),exp(s(map(log,a))/l),(s(map(pow,a,l*[2]))/l)**.5)

ลองออนไลน์!

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


อีกทางเลือกหนึ่งสำหรับความแม่นยำทศนิยม 9:

Python 3 , 169 ไบต์

from math import*
s=sum
def f(*a):l=len(a);return(2>len({round(i,9)for i in a}))*a[0]or f(s(a)/l,l/s(map(pow,a,l*[-1])),exp(s(map(log,a))/l),(s(map(pow,a,l*[2]))/l)**.5)

ลองออนไลน์!


1

C # , 173 ไบต์

double m(int n,params double[]a)=>(n<1?a[0]:m(n-1,a.Sum()/a.Length,Math.Pow(a.Aggregate((t,x)=>t*x),1.0/a.Length),a.Length/a.Sum(x=>1/x),Math.Sqrt(a.Sum(x=>x*x)/a.Length)));

ลองออนไลน์!


2
ดูเหมือนว่าจะเป็นตัวแปรที่ต้องส่งผ่านจริงๆ นอกจากนี้คุณต้องรวมusing Systemและusing System.Linqในจำนวนไบต์เนื่องจากจำเป็นสำหรับโปรแกรมที่จะเรียกใช้ คุณสามารถเปลี่ยนคอมไพเลอร์ของคุณเป็น C # Visual Interactive Compiler ซึ่งไม่ต้องการนำเข้าเหล่านั้น นอกจากนี้1.0->1d
ศูนย์รวมแห่งความไม่รู้

1

ทำความสะอาด , 124 ไบต์

import StdEnv
f=avg o limit o iterate\l=let n=toReal(length l)in[avg l,prod l^(1.0/n),n/sum[1.0/x\\x<-l],avg[x*x\\x<-l]^0.5]

ลองออนไลน์!

ทำการดำเนินการจนกว่าผลลัพธ์จะหยุดการเปลี่ยนแปลง

Hurray สำหรับจุดลอยตัวที่มีความแม่นยำ จำกัด !


1

Pyth, 32 ไบต์

h.Wt{H[.OZ@*FZJlZcJscL1Z@.O^R2Z2

ลองออนไลน์ได้ที่นี่หรือตรวจสอบทุกกรณีทดสอบ (บาร์สองดูหมายเหตุด้านล่าง) ในครั้งเดียวที่นี่ ยอมรับอินพุตเป็นรายการ

ดูเหมือนจะมีปัญหาบางอย่างเกี่ยวกับการปัดเศษเนื่องจากอินพุตบางตัวไม่เข้ากันอย่างถูกต้องเมื่อเป็นอย่างอื่น โดยเฉพาะกรณีทดสอบ0.01 100ติดที่ค่า[6.748305820749738, 6.748305820749738, 6.748305820749739, 6.748305820749738]และกรณีทดสอบ1.61 2.41ติดที่[1.9896543776640825, 1.9896543776640825, 1.9896543776640827, 1.9896543776640825]- หมายเหตุในทั้งสองกรณีที่ค่าเฉลี่ยที่ 3 (ค่าเฉลี่ยฮาร์มอนิก) แตกต่างจากกรณีอื่น

ฉันไม่แน่ใจว่าปัญหานี้ทำให้รายการของฉันเป็นโมฆะหรือไม่ แต่ฉันโพสต์ไว้แล้วตามที่ควรจะเป็น หากสิ่งนี้ไม่เป็นที่ยอมรับก็สามารถแก้ไขได้โดยการใส่.RRTก่อนหน้า[เพื่อปัดค่าเฉลี่ยทศนิยม 10 ตำแหน่งตามที่เห็นในชุดทดสอบนี้

h.Wt{H[.OZ@*FZJlZcJscL1Z@.O^R2Z2)Q   Implicit: Q=eval(input())
                                     Trailing )Q inferred
 .W                              Q   Funcitonal while: While condition is true, call inner. Starting value Q
   t{H                               Condition function: current input H
    {H                                 Deduplicate H
   t                                   Discard first value
                                         Empty list is falsey, so while is terminated when means converge
      [.OZ@*FZJlZcJscL1Z@.O^R2Z2)    Inner function: current input Z
              JlZ                      Take length of Z, store in J
       .OZ                             (1) Arithmetic mean of Z
           *FZ                         Product of Z
          @   J                        (2) Jth root of the above
                     L Z               Map each element of Z...
                    c 1                ... to its reciprocal
                   s                   Sum the above
                 cJ                    (3) J / the above
                            R Z        Map each element of Z...
                           ^ 2         ... to its square
                         .O            Arithmetic mean of the above
                        @      2       (4) Square root of the above
      [                         )      Wrap results (1), (2), (3), and (4) in a list
                                         This is used as the input for the next iteration of the loop
h                                    Take the first element of the result, implicit print

เนื่องจากฉันค่อนข้างมั่นใจว่าการคำนวณซ้ำ ๆ จะไม่ข้ามไปยังค่าก่อนหน้าคุณจึงสามารถแทนที่.Wt{Hด้วยu-4 ไบต์ (และเปลี่ยนZเป็นG)
ar4093

1

Japt v2.0a0 -g, 42 38 ไบต์

â ÊÉ?ß[Ux²÷(V=UÊ)¬Ux÷V U×qV V÷Ux!÷1]:U

จะต้องมีวิธีที่สั้นกว่า ... นี่คือความน่ากลัว! บันทึกแล้ว 4 ไบต์ขอบคุณ @Shaggy!

ลองมัน


38 ไบต์ แต่ฉันเห็นด้วยจะต้องมีวิธีที่สั้นกว่า!
Shaggy

1

C # (Visual C # Interactive คอมไพเลอร์) , 177 ไบต์

double f(double[]g)=>g.All(c=>Math.Abs(c-g[0])<1e-9)?g[0]:f(new[]{g.Sum()/(z=g.Length),Math.Pow(g.Aggregate((a,b)=>a*b),1d/z),z/g.Sum(x=>1/x),Math.Sqrt(g.Sum(x=>x*x)/z)});int z;

ขอบคุณ @KevinCruijjsen สำหรับการชี้ให้เห็นว่าการใช้ความแม่นยำจุดลอยตัวก่อให้เกิดปัญหา! จะเป็น 163 ไบต์หากมีความแม่นยำเป็นสองเท่า

ลองออนไลน์!


กรณีทดสอบสองครั้งล่าสุดให้StackOverflowExceptionความแม่นยำเนื่องจากจุดลอยตัว แทนที่จะc==g[0]ทำอย่างMath.Abs(c-g[0])<1e-9นั้น ลองออนไลน์
Kevin Cruijssen

@KevinCruijssen ขอบคุณมันช่างเป็นความเจ็บปวดที่จัดการกับตัวเลขจุดลอยตัว
ศูนย์รวมแห่งความไม่รู้

1

รหัสเครื่อง x86 (SIMD 4x float โดยใช้ 128-bit SSE1 & AVX) 94 ไบต์

รหัสเครื่อง x86 (SIMD 4x สองเท่าโดยใช้ AVX 256 บิต) 123 ไบต์

floatผ่านกรณีทดสอบในคำถาม แต่ด้วยขีด จำกัด การออกจากลูปขนาดเล็กพอที่จะทำให้เกิดขึ้นได้ง่าย ๆ ที่จะติดอยู่ในการวนซ้ำไม่สิ้นสุดด้วยอินพุตแบบสุ่ม

คำสั่ง SSE1 แบบบรรจุเดียวมีความยาว 3 ไบต์ แต่คำสั่ง SSE2 และคำสั่ง AVX แบบง่ายมีความยาว 4 ไบต์ (คำแนะนำแบบสเกลาร์แบบเดียวเช่นsqrtssนั้นมีความยาว 4 ไบต์ด้วยเหตุนี้ฉันจึงใช้sqrtpsแม้ว่าฉันจะใส่ใจแค่องค์ประกอบที่ต่ำเท่านั้นมันไม่ได้ช้ากว่า sqrts บนฮาร์ดแวร์ที่ทันสมัย) ฉันใช้ AVX สำหรับปลายทางที่ไม่ทำลายเพื่อบันทึก 2 ไบต์เทียบกับ movaps + op
ในรุ่นสองเรายังสามารถทำคู่movlhpsเพื่อคัดลอกชิ้น 64 บิต (เพราะบ่อยครั้งที่เราเพียง แต่ดูแลเกี่ยวกับองค์ประกอบที่ต่ำของผลรวมแนวนอน) ผลรวมของแนวนอน 256 บิต SIMD เวกเตอร์ยังต้องเป็นพิเศษvextractf128ที่จะได้รับในช่วงครึ่งสูงเมื่อเทียบกับ2x ช้า แต่มีขนาดเล็กhaddpsกลยุทธ์ในการลอย doubleรุ่นยังต้องการค่าคงที่ 2x 8 ไบต์แทน 2x 4 ไบต์ โดยรวมแล้วจะออกมาใกล้เคียงกับขนาด 4/3 ของfloatรุ่น

mean(a,b) = mean(a,a,b,b)สำหรับทั้ง 4 วิธีนี้เราสามารถทำซ้ำอินพุตได้สูงสุด 4 อิลิเมนต์และไม่ต้องใช้ความยาว = 2 ดังนั้นเราสามารถ hardcode เรขาคณิตหมายถึงเป็น 4-root = sqrt (sqrt) ตัวอย่างเช่น และเราต้องการค่าคงที่หนึ่ง FP เท่านั้น, 4.0.

เรามีเวกเตอร์ SIMD เดียวทั้ง 4 [a_i, b_i, c_i, d_i]ตัว จากนั้นเราคำนวณ 4 หมายถึงสเกลาร์ในรีจิสเตอร์แยกกันและสับกลับเข้าด้วยกันสำหรับการทำซ้ำครั้งถัดไป (การใช้งานในแนวนอนบนเวกเตอร์ SIMD นั้นไม่สะดวก แต่เราต้องทำสิ่งเดียวกันสำหรับทั้ง 4 องค์ประกอบในกรณีที่มันเพียงพอฉันเริ่มต้นรุ่น x87 แต่มันเริ่มยาวและไม่สนุกเลย)

เงื่อนไข loop-exit ของ}while(quadratic - harmonic > 4e-5)(หรือค่าคงที่ที่น้อยกว่าdouble)ขึ้นอยู่กับคำตอบ R ของ @ RobinRyderและคำตอบ Java ของ Kevin Cruijssen : ค่าสมการกำลังสองเป็นขนาดที่ใหญ่ที่สุดเสมอและค่าเฉลี่ยฮาร์มอนิกจะเล็กที่สุดเสมอ ดังนั้นเราสามารถตรวจสอบเดลต้าระหว่างสองคนนี้เพื่อตรวจจับการลู่เข้า เราคืนค่าเฉลี่ยเลขคณิตเป็นผลลัพธ์สเกลาร์ โดยปกติแล้วระหว่างสองสิ่งเหล่านี้และอาจเป็นข้อผิดพลาดที่ปัดเศษได้น้อยที่สุด

รุ่นลูกลอย : callable เช่นเดียวfloat meanmean_float_avx(__m128);กับหาเรื่องและส่งกลับค่าใน xmm0 (ดังนั้น x86-64 System V หรือ Windows x64 vectorcall แต่ไม่ใช่ x64 fastcall) หรือประกาศ return-type __m128เพื่อที่คุณจะได้ค่าเฉลี่ยกำลังสองและฮาร์มอนิกสำหรับการทดสอบ

การปล่อยให้สิ่งนี้แยก 2 ส่วนfloatใน xmm0 และ xmm1 จะมีราคาเพิ่ม 1 ไบต์: เราต้องการ a ที่shufpsมี imm8 (แทนที่จะเป็นเพียงunpcklps xmm0,xmm0) เพื่อสับเปลี่ยนกันและทำซ้ำ 2 อินพุต

    40  address                    align 32
    41          code bytes         global meanmean_float_avx
    42                             meanmean_float_avx:
    43 00000000 B9[52000000]           mov      ecx, .arith_mean      ; allows 2-byte call reg, and a base for loading constants
    44 00000005 C4E2791861FC           vbroadcastss  xmm4, [rcx-4]    ; float 4.0
    45                             
    46                                 ;; mean(a,b) = mean(a,b,a,b) for all 4 types of mean
    47                                 ;; so we only ever have to do the length=4 case
    48 0000000B 0F14C0                 unpcklps xmm0,xmm0          ; [b,a] => [b,b,a,a]
    49                             
    50                                 ; do{ ... } while(quadratic - harmonic > threshold);
    51                             .loop:
    52                             ;;; XMM3 = geometric mean: not based on addition.  (Transform to log would be hard.  AVX512ER has exp with 23-bit accuracy, but not log.  vgetexp = floor(lofg2(x)), so that's no good.)
    53                                 ;; sqrt once *first*, making magnitudes closer to 1.0 to reduce rounding error.  Numbers are all positive so this is safe.
    54                                 ;; both sqrts first was better behaved, I think.
    55 0000000E 0F51D8                 sqrtps   xmm3, xmm0                 ; xmm3 = 4th root(x)
    56 00000011 F30F16EB               movshdup xmm5, xmm3                 ; bring odd elements down to even
    57 00000015 0F59EB                 mulps    xmm5, xmm3
    58 00000018 0F12DD                 movhlps  xmm3, xmm5                 ; high half -> low
    59 0000001B 0F59DD                 mulps    xmm3, xmm5                 ; xmm3[0] = hproduct(sqrt(xmm))
    60                             ;    sqrtps   xmm3, xmm3                 ; sqrt(hprod(sqrt)) = 4th root(hprod)
    61                                 ; common final step done after interleaving with quadratic mean
    62                             
    63                             ;;; XMM2 = quadratic mean = max of the means
    64 0000001E C5F859E8               vmulps   xmm5, xmm0,xmm0
    65 00000022 FFD1                   call     rcx                ; arith mean of squares
    66 00000024 0F14EB                 unpcklps xmm5, xmm3         ; [quad^2, geo^2, ?, ?]
    67 00000027 0F51D5                 sqrtps   xmm2, xmm5         ; [quad,   geo,   ?, ?]
    68                             
    69                             ;;; XMM1 = harmonic mean = min of the means
    70 0000002A C5D85EE8               vdivps   xmm5, xmm4, xmm0    ; 4/x
    71 0000002E FFD1                   call     rcx                ; arithmetic mean (under inversion)
    72 00000030 C5D85ECD               vdivps   xmm1, xmm4, xmm5    ; 4/.  (the factor of 4 cancels out)
    73                             
    74                             ;;; XMM5 = arithmetic mean
    75 00000034 0F28E8                 movaps   xmm5, xmm0
    76 00000037 FFD1                   call     rcx
    77                             
    78 00000039 0F14E9                 unpcklps  xmm5, xmm1           ;     [arith, harm, ?,?]
    79 0000003C C5D014C2               vunpcklps xmm0, xmm5,xmm2      ; x = [arith, harm, quad, geo]
    80                             
    81 00000040 0F5CD1                 subps    xmm2, xmm1        ; largest - smallest mean: guaranteed non-negative
    82 00000043 0F2E51F8               ucomiss  xmm2, [rcx-8]     ; quad-harm > convergence_threshold
    83 00000047 73C5                   jae     .loop
    84                             
    85                                 ; return with the arithmetic mean in the low element of xmm0 = scalar return value
    86 00000049 C3                     ret
    87                             
    88                             ;;; "constant pool" between the main function and the helper, like ARM literal pools
    89 0000004A ACC52738           .fpconst_threshold:   dd 4e-5    ; 4.3e-5 is the highest we can go and still pass the main test cases
    90 0000004E 00008040           .fpconst_4:    dd 4.0
    91                             .arith_mean:               ; returns XMM5 = hsum(xmm5)/4.
    92 00000052 C5D37CED               vhaddps   xmm5, xmm5         ; slow but small
    93 00000056 C5D37CED               vhaddps   xmm5, xmm5
    94 0000005A 0F5EEC                 divps     xmm5, xmm4        ; divide before/after summing doesn't matter mathematically or numerically; divisor is a power of 2
    95 0000005D C3                     ret

    96 0000005E 5E000000           .size:      dd $ - meanmean_float_avx
       0x5e = 94 bytes

(รายชื่อ NASM สร้างขึ้นด้วยnasm -felf64 mean-mean.asm -l/dev/stdout | cut -b -34,$((34+6))-ถอดส่วนรายชื่อออกและกู้คืนซอร์สด้วยcut -b 34- > mean-mean.asm)

ผลรวมแนวนอน SIMD และหารด้วย 4 (เช่นค่าเฉลี่ยเลขคณิต) ถูกนำมาใช้ในฟังก์ชั่นแยกต่างหากที่เราcall(พร้อมตัวชี้ฟังก์ชั่นเพื่อตัดจำหน่ายต้นทุนของที่อยู่) ด้วย4/xก่อน / หลังหรือx^2ก่อนและก่อนและหลังเราจะได้ค่าเฉลี่ยฮาร์มอนิกและค่ากำลังสอง (มันเจ็บปวดที่จะเขียนdivคำแนะนำเหล่านี้แทนการคูณด้วยตัวแทนที่0.25แน่นอน)

ค่าเฉลี่ยเรขาคณิตถูกนำมาใช้แยกกันกับ sqrt คูณและถูกล่ามโซ่ หรือมีหนึ่ง sqrt ก่อนเพื่อลดขนาดเลขชี้กำลังและอาจช่วยความแม่นยำเชิงตัวเลข บันทึกไม่พร้อมใช้งานfloor(log2(x))ผ่าน AVX512 vgetexpps/pdเท่านั้น Exp นั้นใช้งานได้ผ่าน AVX512ER (Xeon Phi เท่านั้น) แต่มีความแม่นยำเพียง 2 -23 เท่านั้น

การผสมคำแนะนำ AVX แบบ 128- บิตและ SSE รุ่นเก่าไม่ใช่ปัญหาด้านประสิทธิภาพ การผสม AVX 256 บิตกับ SSE รุ่นเก่าสามารถใช้กับ Haswell ได้ แต่ใน Skylake อาจเป็นเพียงการสร้างการอ้างอิงเท็จสำหรับคำแนะนำ SSE ฉันคิดว่าdoubleเวอร์ชันของฉันหลีกเลี่ยงการใช้เครือข่าย dep-loop ที่ไม่จำเป็นและคอขวดใน div / sqrt latency / throughput

รุ่นสอง:

   108                             global meanmean_double_avx
   109                             meanmean_double_avx:
   110 00000080 B9[E8000000]           mov      ecx, .arith_mean
   111 00000085 C4E27D1961F8           vbroadcastsd  ymm4, [rcx-8]    ; float 4.0
   112                             
   113                                 ;; mean(a,b) = mean(a,b,a,b) for all 4 types of mean
   114                                 ;; so we only ever have to do the length=4 case
   115 0000008B C4E37D18C001           vinsertf128   ymm0, ymm0, xmm0, 1       ; [b,a] => [b,a,b,a]
   116                             
   117                             .loop:
   118                             ;;; XMM3 = geometric mean: not based on addition.
   119 00000091 C5FD51D8               vsqrtpd      ymm3, ymm0     ; sqrt first to get magnitude closer to 1.0 for better(?) numerical precision
   120 00000095 C4E37D19DD01           vextractf128 xmm5, ymm3, 1           ; extract high lane
   121 0000009B C5D159EB               vmulpd       xmm5, xmm3
   122 0000009F 0F12DD                 movhlps      xmm3, xmm5              ; extract high half
   123 000000A2 F20F59DD               mulsd        xmm3, xmm5              ; xmm3 = hproduct(sqrt(xmm0))
   124                                ; sqrtsd       xmm3, xmm3             ; xmm3 = 4th root = geomean(xmm0)   ;deferred until quadratic
   125                             
   126                             ;;; XMM2 = quadratic mean = max of the means
   127 000000A6 C5FD59E8               vmulpd   ymm5, ymm0,ymm0
   128 000000AA FFD1                   call     rcx                ; arith mean of squares
   129 000000AC 0F16EB                 movlhps  xmm5, xmm3         ; [quad^2, geo^2]
   130 000000AF 660F51D5               sqrtpd   xmm2, xmm5         ; [quad  , geo]
   131                             
   132                             ;;; XMM1 = harmonic mean = min of the means
   133 000000B3 C5DD5EE8               vdivpd   ymm5, ymm4, ymm0    ; 4/x
   134 000000B7 FFD1                   call     rcx                 ; arithmetic mean under inversion
   135 000000B9 C5DB5ECD               vdivsd   xmm1, xmm4, xmm5    ; 4/.  (the factor of 4 cancels out)
   136                             
   137                             ;;; XMM5 = arithmetic mean
   138 000000BD C5FC28E8               vmovaps  ymm5, ymm0
   139 000000C1 FFD1                   call     rcx
   140                             
   141 000000C3 0F16E9                 movlhps     xmm5, xmm1            ;     [arith, harm]
   142 000000C6 C4E35518C201           vinsertf128 ymm0, ymm5, xmm2, 1   ; x = [arith, harm, quad, geo]
   143                             
   144 000000CC C5EB5CD1               vsubsd   xmm2, xmm1               ; largest - smallest mean: guaranteed non-negative
   145 000000D0 660F2E51F0             ucomisd  xmm2, [rcx-16]           ; quad - harm > threshold
   146 000000D5 77BA                   ja      .loop
   147                             
   148                                 ; vzeroupper ; not needed for correctness, only performance
   149                                 ; return with the arithmetic mean in the low element of xmm0 = scalar return value
   150 000000D7 C3                     ret
   151                             
   152                             ; "literal pool" between the function
   153 000000D8 95D626E80B2E113E   .fpconst_threshold:   dq 1e-9
   154 000000E0 0000000000001040   .fpconst_4:    dq 4.0            ; TODO: golf these zeros?  vpbroadcastb and convert?
   155                             .arith_mean:                     ; returns YMM5 = hsum(ymm5)/4.
   156 000000E8 C4E37D19EF01           vextractf128 xmm7, ymm5, 1
   157 000000EE C5D158EF               vaddpd       xmm5, xmm7
   158 000000F2 C5D17CED               vhaddpd      xmm5, xmm5      ; slow but small
   159 000000F6 C5D35EEC               vdivsd     xmm5, xmm4        ; only low element matters
   160 000000FA C3                     ret

   161 000000FB 7B000000           .size:      dd $ - meanmean_double_avx

    0x7b = 123 bytes

C สายรัดทดสอบ

#include <immintrin.h>
#include <stdio.h>
#include <math.h>

static const struct ab_avg {
    double a,b;
    double mean;
} testcases[] = {
    {1, 1, 1},
    {1, 2, 1.45568889},
    {100, 200, 145.568889},
    {2.71, 3.14, 2.92103713},
    {0.57, 1.78, 1.0848205},
    {1.61, 2.41, 1.98965438},
    {0.01, 100, 6.7483058},
};

// see asm comments for order of  arith, harm, quad, geo
__m128 meanmean_float_avx(__m128);       // or float ...
__m256d meanmean_double_avx(__m128d);    // or double ...
int main(void) {
    int len = sizeof(testcases) / sizeof(testcases[0]);
    for(int i=0 ; i<len ; i++) {
        const struct ab_avg *p = &testcases[i];
#if 1
        __m128 arg = _mm_set_ps(0,0, p->b, p->a);
        double res = meanmean_float_avx(arg)[0];
#else
        __m128d arg = _mm_loadu_pd(&p->a);
        double res = meanmean_double_avx(arg)[0];
#endif
        double allowed_diff = (p->b - p->a) / 100000.0;
        double delta = fabs(p->mean - res);
        if (delta > 1e-3 || delta > allowed_diff) {
            printf("%f %f => %.9f but we got %.9f.  delta = %g allowed=%g\n",
                   p->a, p->b, p->mean, res, p->mean - res, allowed_diff);
        }
    }



    while(1) {
        double a = drand48(), b = drand48();  // range= [0..1)
        if (a>b) {
            double tmp=a;
            a=b;
            b=tmp; // sorted
        }
//      a *= 0.00000001;
//      b *= 123156;
        // a += 1<<11;  b += (1<<12)+1;  // float version gets stuck inflooping on 2048.04, 4097.18 at fpthreshold = 4e-5

        // a *= 1<<11 ; b *= 1<<11;   // scaling to large magnitude makes sum of squares loses more precision
        //a += 1<<11; b+= 1<<11;   // adding to large magnitude is hard for everything, catastrophic cancellation
#if 1
        printf("testing float %g, %g\n", a, b);
        __m128 arg = _mm_set_ps(0,0, b, a);
        __m128 res = meanmean_float_avx(arg);
        double quad = res[2], harm = res[1];  // same order as double... for now
#else
        printf("testing double %g, %g\n", a, b);
        __m128d arg = _mm_set_pd(b, a);
        __m256d res = meanmean_double_avx(arg);
        double quad = res[2], harm = res[1];
#endif
        double delta = fabs(quad - harm);
        double allowed_diff = (b - a) / 100000.0; // calculated in double even for the float case.
        // TODO: use the double res as a reference for float res
        // instead of just checking quadratic vs. harmonic mean

        if (delta > 1e-3 || delta > allowed_diff) {
            printf("%g %g we got q=%g, h=%g, a=%g.  delta = %g,  allowed=%g\n",
                   a, b, quad, harm, res[0], quad-harm, allowed_diff);
        }
    }

}

สร้างด้วย:

nasm -felf64 mean-mean.asm &&
gcc -no-pie -fno-pie -g -O2 -march=native mean-mean.c mean-mean.o

เห็นได้ชัดว่าคุณต้องการซีพียูที่รองรับ AVX หรืออีมูเลเตอร์เช่น Intel SDE เมื่อต้องการคอมไพล์บนโฮสต์โดยไม่รองรับ AVX ดั้งเดิมให้ใช้-march=sandybridgeหรือ-mavx

เรียกใช้: ผ่านกรณีทดสอบแบบกำหนดค่าตายตัว แต่สำหรับรุ่นลอยกรณีทดสอบแบบสุ่มมักจะล้มเหลวใน(b-a)/10000เกณฑ์ที่กำหนดไว้ในคำถาม

$ ./a.out
 (note: empty output before the first "testing float" means clean pass on the constant test cases)
testing float 3.90799e-14, 0.000985395
3.90799e-14 0.000985395 we got q=3.20062e-10, h=3.58723e-05, a=2.50934e-05.  delta = -3.5872e-05,  allowed=9.85395e-09
testing float 0.041631, 0.176643
testing float 0.0913306, 0.364602
testing float 0.0922976, 0.487217
testing float 0.454433, 0.52675
0.454433 0.52675 we got q=0.48992, h=0.489927, a=0.489925.  delta = -6.79493e-06,  allowed=7.23169e-07
testing float 0.233178, 0.831292
testing float 0.56806, 0.931731
testing float 0.0508319, 0.556094
testing float 0.0189148, 0.767051
0.0189148 0.767051 we got q=0.210471, h=0.210484, a=0.21048.  delta = -1.37389e-05,  allowed=7.48136e-06
testing float 0.25236, 0.298197
0.25236 0.298197 we got q=0.274796, h=0.274803, a=0.274801.  delta = -6.19888e-06,  allowed=4.58374e-07
testing float 0.531557, 0.875981
testing float 0.515431, 0.920261
testing float 0.18842, 0.810429
testing float 0.570614, 0.886314
testing float 0.0767746, 0.815274
testing float 0.118352, 0.984891
0.118352 0.984891 we got q=0.427845, h=0.427872, a=0.427863.  delta = -2.66135e-05,  allowed=8.66539e-06
testing float 0.784484, 0.893906
0.784484 0.893906 we got q=0.838297, h=0.838304, a=0.838302.  delta = -7.09295e-06,  allowed=1.09422e-06

ข้อผิดพลาดของ FP นั้นเพียงพอที่ความเสียหายของรูปสี่เหลี่ยมจะน้อยกว่าศูนย์สำหรับอินพุตบางตัว

หรือไม่ใส่a += 1<<11; b += (1<<12)+1;เครื่องหมายข้อคิดเห็น:

testing float 2048, 4097
testing float 2048.04, 4097.18
^C  (stuck in an infinite loop).

doubleไม่มีปัญหาเหล่านี้เกิดขึ้นกับ ใส่ข้อคิดเห็นprintfก่อนการทดสอบแต่ละครั้งเพื่อดูว่าเอาต์พุตว่างเปล่า (ไม่มีอะไรจากif(delta too high)บล็อก)

สิ่งที่ต้องทำ: ใช้doubleเวอร์ชันเป็นข้อมูลอ้างอิงสำหรับfloatเวอร์ชันแทนที่จะดูว่าพวกเขามาบรรจบกันกับรูปสี่เหลี่ยมอันตรายอย่างไร


1

Javascript - 186 ไบต์

รับอินพุตเป็นอาร์เรย์ของตัวเลข ใช้การแปลงค่าเฉลี่ยในคำตอบของ J42161217เพื่อย่อโค้ด

ลองใช้ออนไลน์

f=(v,l=[m=(w,k=0)=>w.map(x=>k+=x)&&k/w.length,w=>1/m(w.map(x=>1/x)),w=>Math.E**m(w.map(x=>Math.log(x))),w=>m(w.map(x=>x**2))**.5].map(x=>x(v)).sort((a,b)=>a-b))=>l[3]-l[0]>1e-5?f(l):l[0]

คำอธิบาย

f = (
  v,
  l=[
    m=(w,k=0)=>w.map(x=>k+=x)&&k/w.length,  // m = w => arithmetic mean of values in w
    w=>1/m(w.map(x=>1/x)),                  // w => harmonic mean of values in w   
    w=>Math.E**m(w.map(x=>Math.log(x))),    // w => geometric mean of values in w   
    w=>m(w.map(x=>x**2))**.5                // w => quadratic mean of values in w   
  ].map(x=>x(v))                            // get array of each mean using input v, stored in l
  .sort((a,b)=>a-b)                         // sort the outputs
) =>
  l[3] - l[0] > 1e-5 ?                      // is the difference between the largest
                                            // and smallest means > 1/100000?
    f(l) :                                  // if yes, get the mean mean of the means
    l[0]                                    // if no, arbitrarily return the smallest value
                                            // as close enough

ฉันคิดว่าฉันจะฉลาดและใช้ความสัมพันธ์กับลอการิทึมแต่ดูเหมือนคุณและ J42161217 มาถึงที่นั่นก่อน!
Pureferret

@Pureferret ฉันไม่ให้เครดิตฉันอย่างโจ๋งครึ่มขโมยมัน: D
asgallant

คุณเขียนมันใน JavaScript แม้ว่า!
Pureferret

1
นั่นเป็นส่วนที่ง่าย การเล่นกอล์ฟมันยาก
asgallant

1
TIL ไม่ได้รับการกำหนดค่าอย่างถูกต้อง ฉันเพิ่มลิงค์ TIL ลงในคำตอบ
asgallant


0

SNOBOL4 (CSNOBOL4) , 296 ไบต์

	X =INPUT
	Y =INPUT
	A =(X + Y) / 2.
	P =X * Y
	G =P ^ 0.5
	H =P / A
	Q =(2 * (A ^ 2) - P) ^ 0.5
O	OUTPUT =EQ(Q,A) Q	:S(END)
	M =A
	N =G
	O =H
	P =Q
	A =(M + N + O + P) / 4
	G =(M * N * O * P) ^ 0.25
	H =4 / (1 / M + 1 / N + 1 / O + 1 / P)
	Q =((M ^ 2 + N ^ 2 + O ^ 2 + P ^ 2) / 4) ^ 0.5	:(O)
END

ลองออนไลน์!

การใช้งานที่ไม่ซับซ้อน ใช้เคล็ดลับจากคำตอบของฉันไปยังคำถามที่เกี่ยวข้องกับการเล่นกอล์ฟอีกเล็กน้อย

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