Dòng AGM Lỗ 1: Tính toán trung bình hình học số học


26

Câu hỏi này được lấy cảm hứng từ HNQ này .

Về bộ truyện

Câu hỏi này bây giờ là một phần của loạt bài về phương pháp AGM. Bài đầu tiên trong loạt bài này sẽ là về việc tính toán thực sự AGM. Bạn có thể coi điều này giống như bất kỳ thử thách golf mã nào khác, và trả lời nó mà không phải lo lắng về loạt bài này. Tuy nhiên, có một bảng xếp hạng trên tất cả các thách thức.

Ý nghĩa hình học số học là gì

Các Arithmetic-Geometric Mean của hai số được định nghĩa là số đó nhiều lần tham gia các phương tiện số học và hình học hội tụ đến. Nhiệm vụ của bạn là tìm số này sau một số nlần lặp.

Làm rõ

  • Bạn lấy ba số, a, b, ntrong bất kỳ định dạng hợp lý.
  • Đối với nlần lặp lại, lấy giá trị trung bình số học và hình học của abvà thiết lập những để ab.
  • Đối với hai số ab, trung bình số học được định nghĩa là (a + b) / 2.
  • Trung bình hình học được định nghĩa là √(a * b).
  • abnên tiếp cận nhau.
  • Sau đó, đầu ra cả ab.
  • Bạn không phải lo lắng về sự thiếu chính xác và như vậy.
  • Đây là để mã ngắn nhất tính theo byte thắng!

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

[0, [24, 6]] -> [24, 6]    
[1, [24, 6]] -> [15.0, 12.0]
[2, [24, 6]] -> [13.5, 13.416407864998739]
[5, [24, 6]] -> [13.458171481725616, 13.458171481725616]
[10, [100, 50]] -> [72.83955155234534, 72.83955155234534]

The next one is 1/Gauss's Constant:
[10, [1, 1.41421356237]] -> [1.198140234734168, 1.1981402347341683]

Bảng xếp hạng

Bị đánh cắp từ loạt của Martin.

Đoạn mã sau sẽ tạo bảng xếp hạng trong tất cả các thử thách của loạt bài.

Để đảm bảo rằng câu trả lời của bạn hiển thị, vui lòng bắt đầu mọi câu trả lời bằng tiêu đề, sử dụng mẫu Markdown sau:

# Language Name, N bytes

Trong đó N là kích thước của trình của bạn. Nếu bạn cải thiện điểm số của mình, bạn có thể giữ điểm số cũ trong tiêu đề, bằng cách đánh bại chúng thông qua. Ví dụ:

# Ruby, <s>104</s> <s>101</s> 96 bytes


1
Là số nguyên ban đầu là số nguyên dương?
xnor

2
" Cả hai ahayb " ,wellwell, cái nào? Cả hai, hoặc một trong hai?
Doorknob

@Doorknob -_- Cả hai.
Maltysen

1
@xnor không. Nhìn vào trường hợp thử nghiệm cuối cùng.
Maltysen

5
Làm cho phần này của một loạt gây ra một loại tình huống không may. Điều này đơn giản đến mức tất cả các giải pháp sẽ trông khá giống nhau. Và đăng các giải pháp tương tự trong các ngôn ngữ đã được sử dụng thường được tán thành. Tôi đã viết giải pháp của mình trong khoảng 2 phút, nhưng đó là ngôn ngữ đã được sử dụng và nó có cùng độ dài. Nếu tôi tuân theo nghi thức đăng bài thông thường, tôi sẽ không thể tham gia vào bộ truyện.
Reto Koradi

Câu trả lời:



9

APL Dyalog , 22 21 15 byte

.5∘(+.×,×.*⍨)⍣⎕

Lấy ( a , b ) làm đối số đúng và nhắc cho n :

(

  +.× chấm sản phẩm 0,5 và đối số đúng

, theo dõi bởi

  ×.*⍨"sức mạnh chấm" của đối số đúng và 0,5 *

)⍣⎕ áp dụng thời gian nhắc số.

* "dot power" giống như sản phẩm chấm, nhưng sử dụng phép nhân và công suất thay vì cộng và nhân, như sau:

      n
A ×.*⍨ B B i A = B 1 A B 2 A
      i = 1

-3 byte nhờ ngn.


Phiên bản cũ:

{((+/÷≢),.5*⍨×/)⍣⍺⊢⍵}

Đưa ra nnhư đối số trái và a bnhư đối số phải.

⊢⍵Trên RightArg
(... )⍣⍺tính toán lại
(+/÷≢)tổng số lần LeftArg chia cho kiểm đếm
,theo
.5*⍨×/căn bậc hai của sản phẩm.

Tất cả các trường hợp thử nghiệm:

      f←{((.5×+/),.5*⍨×/)⍣⍺⊢⍵}
      0 1 2 5 10 10 f¨ (24 6)(24 6)(24 6)(24 6)(100 50)(1,2*.5)
┌────┬─────┬────────────────┬───────────────────────┬───────────────────────┬───────────────────────┐
│24 6│15 12│13.5 13.41640786│13.45817148 13.45817148│72.83955155 72.83955155│1.198140235 1.198140235│
└────┴─────┴────────────────┴───────────────────────┴───────────────────────┴───────────────────────┘

f⍣⍺⊢⍵hoặc tương tự một thành ngữ bạn sử dụng chuyên nghiệp?
lirtosiast

@ThomasKwa Có, xem ví dụ Of⍣core⊢TREEtại miserver.dyalog.com (nhấp vào "D" lớn và cuộn đến dòng [266]).
Adám

7

TI-BASIC, 22 byte

Input N
For(I,1,N
{mean(Ans),√(prod(Ans
End
Ans

Liệu chính xác những gì thuật toán nói. Đưa N từ dấu nhắc và A và B qua Ansdanh sách hai phần tử.

Nếu N bằng 0, For(vòng lặp được bỏ qua hoàn toàn.


6

JavaScript ES7, 48 43 byte

-5 cảm ơn Hạ cấp!

f=(n,a,b)=>n?f(n-1,(a+b)/2,(a*b)**.5):[a,b]

Hàm đệ quy rất đơn giản.


2
(a*b)**.5ngắn hơn Math.sqrt(a*b). ví dụ
Downgoat

@Downgoat Đó là ES7, nhưng meh.
Conor O'Brien

6

MATLAB / Octave, 69 65 byte

function [a,b]=r(a,b,n)
for i=1:n;j=(a+b)/2;b=(a*b)^.5;a=j;end

1
Bạn có thể làm b=(a*b).^5trực tiếp vì bạn không sử dụng blại lần nữa trong lần lặp đó và lưu 4 byte.
Brain Guider

6

Thạch, không cạnh tranh

9 byte Câu trả lời này không có tính cạnh tranh, vì nó sử dụng các tính năng trì hoãn thử thách.

SH;P½¥ðṛ¡

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

Làm thế nào nó hoạt động

SH;P½¥ðṛ¡    Input: x (vector) -- y (repetitions)

SH           Take the sum (S) of x and halve (H) the result.
   P½        Take the product (P) of x and the square root (½) of the result.
     ¥       Combine the last two instructions in a dyadic chain.
  ;          Concatenate the results to the left and to the right.
      ð      Push the preceding, variadic chain; begin a new, dyadic chain.
       ṛ     Return the right argument (y).
        ¡    Repeat the pushed chain y times.

5

Nghiêm túc, 11 byte

,p`;π√@æk`n

Bãi rác Hex:

2c70603be3fb40916b606e

Dùng thử trực tuyến

Giải trình:

,                    Read in the list as [n,a,b]
 p                   pop list to yield: n [a,b]
  `      `n          Push a quoted function and run it n times.
   ;                 Duplicate [a,b] pair
    π√               Compute its product and square root it (GM)
      @              Swap the other copy of the pair to the top
       æ             Compute its mean.
        k            Compile the stack back into a list.

5

C ++, 108 102 100 byte

Cảm ơn bạn @RetoKoradi và @AlexA vì đã tiết kiệm cho tôi 6 byte.

Điều này là không cạnh tranh, vì C ++ không phải là một ngôn ngữ chơi golf tốt. Đã làm điều này cho vui :)

#include<cmath>
std::string f(float a,float b,int n){return n==0?a+" "+b:f((a+b)/2,sqrt(a*b),n-1);}

Đây là một hàm đệ quy đơn giản, rất giống với câu trả lời JS.


3
Bạn có thể thoát khỏi khoảng trắng sau dấu phẩy. Ngoài ra, sử dụng floatthay vì doublengắn hơn.
Reto Koradi

1
Bạn cũng có thể loại bỏ không gian trong #includedòng.
Alex A.

Wow, tôi thật ngu ngốc khi không chú ý điều đó. Cảm ơn!
TheCoffeeCup

Tôi sẽ xem xét việc f(float*s)đưa một con trỏ đến 3 float là "định dạng hợp lý". Không chắc chắn nếu điều đó thực sự làm cho nó ngắn hơn.
nwp

4

K5, 15 byte

Rất đúng nghĩa

{(+/x%2;%*/x)}/

Trong hành động:

 {(+/x%2;%*/x)}/[0; 24 6]
24 6
 {(+/x%2;%*/x)}/[5; 24 6]
1.345817e1 1.345817e1

Thật không may, điều này không hoạt động trong oK bởi vì trình thông dịch đó hiện không hỗ trợ phép chiếu (currying) của trạng từ. Hoạt động trong k5 thực.

Trong oK, hiện tại cần phải bọc định nghĩa trong lambda:

  {x{(+/x%2;%*/x)}/y}[5; 24 6]
13.4582 13.4582

4

J, 18 13 byte

-:@+/,%:@*/^:

Sử dụng:

   agm =: -:@+/,%:@*/^:
   5 agm 24 6
13.4582 13.4582

Wow, cái này hoạt động. Kết hợp là lạ. Tôi hy vọng biểu thức này là một trạng từ (có thể là như vậy), nhưng nếu được trình bày với các đối số thì đó cũng là một hàm.
ngẫu nhiên

3

Japt , 24 byte 25 33

Đã lưu 9 7 byte nhờ @ETHproductions

Uo r@[VW]=[V+W /2(V*W q]

Tận dụng lợi thế của việc phá hủy ES6.

Dùng thử trực tuyến

Ungolfed && Giải thích

Uo r@[VW]=[V+W /2(V*W q]

       // Implicit: U: 1st input, V: 2nd input, W: 3rd input
Uo     // Range from 0 to 1st input
r@     // Loop over range
  [V,W]=    // Set 2nd and 3rd input to...
   [V+W /2,   // Add 2nd and 3rd inputs, divide by 2
   (V*W q]    // Multiple 2nd and 3rd inputs, find square root
            // Set's to the above respectively 
       // Implicit: return [V,W]

Uotạo ra một phạm vi các số từ 0 đến U, do đó Uo m@[V,W]=[V+W /2,(V*W q]nên hoạt động. (Chưa được kiểm tra)
ETHproductions 9/12/2015

Ồ, và bạn không cần phải có dấu phẩy. :)
Sản phẩm ETH

@ETHproductions cảm ơn một lần nữa! :)
Hạ cấp

Ôi trời ơi, điều này không thành công cho bất kỳ ai Ukhác ngoài 1, xuất ra từng vòng lặp khi nó diễn ra. Đây là một hoạt động đúng:Uo £[VW]=[V+W /2(V*W q]};[VW]
ETHproductions 9/12/2015

@ETHproductions cảm ơn, nhưng sử dụng rdường như cũng hoạt động
Downgoat

3

Matlab, 54 byte

function x=f(x,n)
for k=1:n
x=[mean(x) prod(x)^.5];end

Thí dụ:

>> f([24 6], 2)
ans =
  13.500000000000000  13.416407864998739

3

Bình 12 tháng 12

u,.OG@*FG2EQ

Phòng thử nghiệm

Giải trình

u,.OG@*FG2EQ    ##  implicit: Q = eval(input())
u         EQ    ##  reduce eval(input()) times, starting with Q
                ##  the reduce lambda has G as the previous value and H as the next
  .OG           ##  arithmetic mean of last pair
     @*FG2      ##  geometric mean of last pair, uses *F to get the product of the list
                ##  and @...2 to get the square root of that
 ,              ##  join the two means into a two element list

Quên @.O, nhưng tôi thậm chí không biết mục đích mới E.
orlp

@orlp ah, không thấy bài viết của bạn, tôi xấu tôi sẽ chỉ đề xuất những điều này trong các bình luận. Và vâng, theo dõi tất cả những thứ thay đổi là một cuộc đấu tranh: P
FryAmTheEggman

2

Chồnolang v0,14, 23 byte

Hãy thử nó ở đây !

$n[$d+2$:r*1Mi2%?!r]$N.
$n                      C get all input C
  [                ]    C pop N; repeat inner N times C
   $d                   C duplicate stack [1,2] => [1,2,1,2] C
     +                  C add top two elements C
      2$:               C divide by two C
         r              C reverse stack (get the other two) C
          *             C multiply them together C
           1M           C take square root C
             i2%?!r     C reverse the stack if an odd step number C
                    $N  C output stack
           1M           C take square root C
             i          C get step in for loop C


2

Python 3, 65 55 byte

Cảm ơn mathmandan vì đã chỉ ra một phiên bản ngắn hơn bằng cách sử dụng lambdatoán tử.

f=lambda a,b,n:f((a+b)/2,(a*b)**.5,n-1)if n else(a,b)

Phiên bản gốc của tôi:

def f(a,b,n):
 if n:f((a+b)/2,(a*b)**.5,n-1)
 else:print(a,b)

Theo tôi, một hàm đệ quy (a la các câu trả lời JavaScript và C ++) ngắn hơn một vòng lặp đơn giản.


2
Bạn có thể rút ngắn điều này một chút với lambdavà toán if/elsetử ternary :f=lambda a,b,n:f((a+b)/2,(a*b)**.5,n-1)if n else(a,b)
mathmandan

Không vấn đề gì! (Ngoài ra, tôi nghĩ rằng đây là 53 byte.)
mathmandan

Tệp .py tôi đã lưu được liệt kê là 55 byte. Có cách nào tốt hơn để tính kích thước chương trình?
Jack Brounstein

Đôi khi mọi người trên trang web này sao chép và dán mã của họ vào Mothereff.in/byte-count . Nếu bạn đang tự hỏi về sự khác biệt này, tôi đoán rằng Windows đang chèn một ký tự dòng mới không cần thiết vào cuối tệp .py của bạn (và Windows tính một dòng mới là 2 byte thay vì 1). Dù bằng cách nào, bạn không phải tính dòng mới đó là một phần của mã cho mục đích ghi điểm. Nếu bạn đăng một mục nhập nhiều dòng, bạn nên tính 1 cho mỗi ký tự dòng mới, không phải 2 và không bao gồm bất kỳ dòng mới nào ở cuối dòng mã cuối cùng của bạn. (Theo như tôi hiểu các quy tắc nào!)
mathmandan

2

R, 66 byte

f=function(a,b,n){while(n){x=(a+b)/2;b=(a*b)^.5;n=n-1;a=x};c(a,b)}

Sử dụng:

> f(24,6,0)
[1] 24  6
> f(24,6,1)
[1] 15 12
> f(24,6,2)
[1] 13.50000 13.41641
> f(24,6,3)
[1] 13.45820 13.45814
> f(24,6,4)
[1] 13.45817 13.45817
> f(100,50,10)
[1] 72.83955 72.83955
> f(1,1.41421356237,10)
[1] 1.19814 1.19814

Bạn có thể xóa tên hàm để lưu 2 byte.
Alex A.

2

Toán học, 31 30 byte

Lưu một byte nhờ Martin Büttner.

{+##/2,(1##)^.5}&@@#&~Nest~##&

Sử dụng:

In[1]:= {+##/2,(1##)^.5}&@@#&~Nest~##&[{24, 6}, 5]

Out[1]= {13.4582, 13.4582}

1

Lua, 62 byte

n,a,b=...for i=1,n do a,b=(a+b)/2,math.sqrt(a*b)end print(a,b)

Sử dụng các đối số dòng lệnh ...để gán cho n, ab, một mẹo tiện lợi mà tôi đã học về Lua gần đây.


1

Haskell, 40 byte

(!!).iterate(\(a,b)->((a+b)/2,sqrt$a*b))

Một chức năng ẩn danh. Ví dụ sử dụng:

>> let f=(!!).iterate(\(a,b)->((a+b)/2,sqrt$a*b)) in f (1.0,1.41421356237) 10
(1.198140234734168,1.1981402347341683)

Hàm lambda (\(a,b)->((a+b)/2,sqrt$a*b))có ý nghĩa số học và hình học trên một tuple. Điều này được lặp lại bắt đầu với đầu vào đầu tiên (một tuple), và sau đó (!!)lập chỉ mục đầu vào thứ hai để chỉ định số lần lặp.


1

Perl, 60 byte

perl -ape'F=($F[0]/2+$F[1]/2,sqrt$F[0]*$F[1])for 1..shift@F;$_="@F"'

NB: Mỗi bài đăng meta này , tôi tin rằng tôi đã ghi điểm chính xác. Mã thực tế (giữa các dấu ngoặc đơn) là 58 ký tự, sau đó tôi đã thêm +2 cho ap cờ vì đó là sự khác biệt so với lời mời ngắn nhất,perl -e'...'

Khiếu nại mơ hồ

Tôi có cảm giác khó chịu này Tôi đang thiếu một sự cải thiện rõ ràng. Tôi biết, "hoan nghênh chơi golf", nhưng ý tôi là nhiều hơn bình thường tôi tin rằng có một cơ hội dễ dàng để rút ngắn điều này.

Ban đầu, tôi đã loay hoay với việc sử dụng $\như thuật ngữ thứ hai với một số thành công, nhưng cách tiếp cận ở trên kết thúc ngắn hơn 2 byte, ngay cả với các apcờ bổ sung cần thiết. Tương tự, tránh rõ ràng$_ gán sẽ tốt, nhưng vòng lặp làm cho điều đó trở nên khó khăn.

Các shift@Flỗi tôi cũng vậy; mặc dù nếu tôi không làm theo cách đó, mặc dù (hoặc sử dụng @F=(0,...,...)thay vào đó, không lưu bất kỳ byte nào), sẽ có một lỗi xảy ra với @Fbài tập.

Thí dụ

echo 5 24 6 | perl -ape'F=($F[0]/2+$F[1]/2,sqrt$F[0]*$F[1])for 1..shift@F;$_="@F"'

Đầu ra

13.4581714817256 13.4581714817256

1

Julia, 49 byte

(a,b,n)->(for i=1:n;a,b=(a+b)/2,√(a*b)end;(a,b))

Thuật toán lặp trực tiếp khá. Sử dụng ký hiệu và trả về nhiều sẽ tiết kiệm được một vài byte, nhưng cú pháp vòng lặp for tốn một vài chi phí.


1

Haskell, 47 byte

f a b 0=(a,b)
f a b n=f((a+b)/2)(sqrt$a*b)(n-1)

bạn có thể lưu một số byte lấy ab thành một cặp trong f: fx 0 = x; f (a, b) n = f ((a + b) / 2, sqrt $ a * b) $ n-1
Damien

Và xác định hàm infix.
xnor

1

Julia, 42 byte

f(a,b,n)=n>0?f((a+b)/2,(a*b)^.5,n-1):(a,b)

Đây là một hàm đệ quy fchấp nhận ba số và trả về một tuple.

Ung dung:

function f(a::Real, b::Real, n::Integer)
    if n > 0
        # Recurse on the arithmetic and geometric means, decrementing n
        return f((a + b) / 2, sqrt(a * b), n - 1)
    else
        # Return the pair
        return (a, b)
    end
end

1

LabVIEW, 21 LabVIEW Nguyên thủy

Nguyên thủy được tính theo bài meta này .

khá rõ ràng không có nhiều để giải thích.


1

Python 2, 62 61 62 byte

def f(a,b,n):
 while n:a,b=(a+b)/2.,(a*b)**.5;n-=1
 print a,b

3
Chương trình chỉ nên in một lần, khi nó kết thúc.
lirtosiast

1
Sự hiểu lầm của tôi. Đã sửa.
wflynny

1

CJam, 16 byte

{{_:+2/\:*mq]}*}

Đây là một chức năng ẩn danh. Đầu vào là một danh sách với hai giá trị (dưới dạng nhân đôi), theo sau là số lần lặp. Hãy thử trực tuyến với mã I / O để thử nghiệm.

Tôi thường không đăng bài này vì @PeterTaylor đã đăng một câu trả lời dài bằng nhau của CJam trước khi tôi thấy câu hỏi. Nhưng vì điều này được quảng cáo là khởi đầu của một bộ truyện, tôi muốn giữ các lựa chọn của mình mở trong trường hợp bộ truyện thú vị.

Mặc dù độ dài giống như câu trả lời của Peter, nhưng mã này thì không. Tôi đã chọn một định dạng đầu vào khác nhau bằng cách lấy hai giá trị trong một danh sách, trong đó Peter sử dụng các giá trị riêng biệt. Vì vậy, trong khi không có nhiều định dạng với định dạng đầu vào, mã trông khá khác nhau.

{     Start loop over number of iterations.
  _     Copy the current pair of values.
  :+    Reduce pair with + operator.
  2/    Divide by 2.
  \     Swap second copy of pair to top.
  :*    Reduce pair with * operator.
  mq    Calculate square root.
  ]     Wrap the two new values in a list for next iteration.
}*    End iteration loop.

0

Perl 6 ,  53  47 byte

{(($^a,$^b),->(\a,\b){((a+b)/2,sqrt(a*b))}...*)[$^n]} # 53 bytes

sử dụng:

# give it a name
my &code = {(($^a,$^b),->(\a,\b){((a+b)/2,sqrt(a*b))}...*)[$^n]}

say code 100,50,10;          # (72.8395515523453 72.8395515523453)
say code 1,1.41421356237,10; # (1.19814023473417 1.19814023473417)

Nếu tôi thay đổi đầu vào từ a,b,nthành (a,b),ntôi có thể lưu một vài byte.

{($^l,->(\a,\b){((a+b)/2,sqrt(a*b))}...*)[$^n]} # 47 bytes

sử dụng:

my &code = {($^l,->(\a,\b){((a+b)/2,sqrt(a*b))}...*)[$^n]}

say code (100,50),10;          # (72.8395515523453 72.8395515523453)
say code (1,1.41421356237),10; # (1.19814023473417 1.19814023473417)

say code (24,6),$_ for 0,1,2,5;
# (24 6)
# (15 12)
# (13.5 13.4164078649987)
# (13.4581714817256 13.4581714817256)
{
  (
    $^l,          # first 2 element tuple
    ->            # pointy block (lambda)
      (\a,\b)     # take a single tuple, and give its 2 elements each a name
    {
      (           # create a 2 element tuple
        (a+b)/2,  # arithmetic mean
        sqrt(a*b) # geometric mean
      )
    } ... *       # create a lazy infinite sequence of tuples
  )[ $^n ]        # take the nth "tuple" from the outer sequence
}

Thực sự tôi sẽ trao đổi ... *với ... -> (\a,\b) { a =~= b }, sau đó sẽ không cần $^ntham số.
(không sử dụng ==thay thế =~=hoặc có thể không dừng lại)

my &code = {($^l,->(\a,\b){((a+b)/2,sqrt(a*b))}...->(\a,\b){a=~=b})[*-1]}

say code (24,6);           # (13.4581714817256 13.4581714817256)
say code (100,50);         # (72.8395515523453 72.8395515523453)
say code (1,1.41421356237) # (1.19814023473417 1.19814023473417)

0

Prolog, 80 byte

Mã số:

p(A,B,0):-write([A,B]).
p(A,B,N):-X is(A+B)/2,Y is sqrt(A*B),M is N-1,p(X,Y,M).

Thí dụ:

p(100,50,10).
[72.83955155234534, 72.83955155234534]

Dùng thử trực tuyến tại đây


0

Java, 103 96 84 byte

String f(int n,double a,double b){return n>0?f(n-1,(a+b)/2,Math.sqrt(a*b)):a+","+b;}

Xác nhận tất cả các testcase.

Phiên bản cũ (96 byte):

String f(int n,double a,double b){for(;n>0;a=(a+b)/2,b=Math.sqrt((b-2*a)*b))n--;return a+","+b;}

Phiên bản cũ (103 byte):

String f(int n,double a,double b){double t;for(;n>0;t=(a+b)/2,b=Math.sqrt(a*b),a=t)n--;return a+","+b;}
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.