AGM 시리즈 구멍 1 : 산술-기하학적 평균 계산


26

이 질문은 이 HNQ 에서 영감을 얻었습니다 .

시리즈 소개

이 질문은 이제 AGM 방법에 대한 시리즈의 일부입니다. 시리즈의 첫 번째 게시물은 실제로를 계산하는 것 AGM입니다. 이것을 다른 코드 골프 도전과 같이 취급하고 시리즈에 대해 전혀 걱정하지 않고 대답 할 수 있습니다. 그러나 모든 과제에는 리더 보드가 있습니다.

산술-기하학적 평균

두 숫자 의 산술-기하 평균산술 및 기하 평균 을 반복적으로 수렴하는 숫자로 정의됩니다. 당신의 임무는 몇 n번의 반복 후에이 번호를 찾는 것 입니다.

설명

  • a, b, n합리적인 형식으로 세 개의 숫자를 사용 합니다.
  • 들면 n반복의 산술 및 기하 평균 소요 ab하고 그 설정 a하고 b.
  • 두 숫자 ab의 경우 산술 평균은로 정의됩니다 (a + b) / 2.
  • 기하 평균은로 정의됩니다 √(a * b).
  • a그리고 b서로 접근해야한다.
  • 그리고, 출력 모두 ab.
  • 플로트 부정확성 등에 대해 걱정할 필요가 없습니다.
  • 이것은 이므로 바이트 단위의 가장 짧은 코드가 승리합니다!

테스트 사례

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

리더 보드

마틴의 시리즈에서 도난당했습니다.

다음 스 니펫은 시리즈의 모든 과제에서 리더 보드를 생성합니다.

답변이 표시되도록하려면 다음 마크 다운 템플릿을 사용하여 모든 답변을 헤드 라인으로 시작하십시오.

# Language Name, N bytes

여기서 N은 제출 크기입니다. 점수를 높이면 헤드 라인을 쳐서 오래된 점수를 유지할 수 있습니다. 예를 들어 :

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


1
초기 숫자는 양의 정수입니까?
xnor

2
" 모두 a또는b "— 어느 쪽입니까? 둘 다 또는 하나?
Doorknob

@Doorknob -_- 둘 다입니다.
Maltysen

1
@xnor no. 마지막 테스트 사례를보십시오.
Maltysen

5
이 시리즈를 만들면 불행한 상황이 발생합니다. 솔루션이 모두 비슷하게 보일 정도로 간단합니다. 이미 사용 된 언어로 유사한 솔루션을 게시하는 것은 일반적으로 싫은 일입니다. 약 2 분 안에 솔루션을 작성했지만 이미 사용 된 언어로 길이는 같습니다. 일반적인 게시 에티켓을 따르면 시리즈에 참여할 수 없습니다.
Reto Koradi

답변:



9

Dyalog APL , 22 21 15 바이트

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

( a , b )를 올바른 인수로 취하고 n을 프롬프트합니다 .

(

  +.× 0.5의 내적과 올바른 주장

, 뒤에

  ×.*⍨올바른 논쟁의 "점 파워"와 0.5 *

)⍣⎕ 숫자 프롬프트 시간을 적용했습니다.

* "dot power"는 내적과 유사하지만 다음과 같이 더하기 및 곱하기 대신 곱셈과 곱셈을 사용합니다.

      n
A ×.*⍨ B B i A = B 1 A B 2 A
       i = 1입니다.

ngn 덕분에 -3 바이트


구 버전:

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

소요 n 왼쪽 인수로 및 a b오른쪽 인자로.

⊢⍵RightArg에서
(... )⍣⍺LeftArg 시간
(+/÷≢)합계를 tally로 나눈
,다음 다시 계산 합니다.
.5*⍨×/ 제품의 제곱근을 합니다.

모든 테스트 사례 :

      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⍣⍺⊢⍵또는 유사한 관용구 당신은 전문적으로 사용할 수 있습니까?
lirtosiast

@ThomasKwa 예는, 예를 들어 볼 Of⍣core⊢TREE에서 miserver.dyalog.com (라인에 큰 "D"와 스크롤을 클릭 [266]).
Adám

7

TI-BASIC, 22 바이트

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

알고리즘이 말하는 것을 정확하게 수행합니다. 프롬프트에서 N을 가져오고 A와 B를 Ans두 요소 목록으로 가져옵니다 .

N이 0이면 For(루프가 완전히 건너 뜁니다.



6

MATLAB / 옥타브, 69 65 바이트

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

1
해당 반복에서 다시 b=(a*b).^5재사용하지 않고 직접 b수행하여 4 바이트를 절약 할 수 있습니다 .
Brain Guider

6

경쟁하지 않는 젤리

9 바이트이 답변은 도전 과제를 수행하는 기능을 사용하므로 경쟁이 아닙니다.

SH;P½¥ðṛ¡

온라인으로 사용해보십시오!

작동 원리

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

진심으로, 11 바이트

,p`;π√@æk`n

육각 덤프 :

2c70603be3fb40916b606e

온라인으로 사용해보십시오

설명:

,                    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 바이트

6 바이트를 절약 해 준 @RetoKoradi와 @AlexA에게 감사합니다.

C ++는 좋은 골프 언어가 아니기 때문에 경쟁이 아닙니다. 재미를 위해 이것을 했습니까 :)

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

이것은 JS 회답과 매우 유사한 간단한 재귀 함수입니다.


3
쉼표 뒤에 공백을 제거 할 수 있습니다. 또한 float대신에 사용 하는 double것이 더 짧습니다.
Reto Koradi

1
#include줄 에서 공백을 제거 할 수도 있습니다 .
Alex A.

와우, 나는 그것을 알지 못하는 바보입니다. 감사!
TheCoffeeCup

f(float*s)3 개의 부동 소수점에 대한 포인터가 "합리적인 형식"이되는 것을 고려할 것 입니다. 그것이 실제로 짧아 지는지 확실하지 않습니다.
nwp

4

K5, 15 바이트

매우 문자 그대로 :

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

실제로 :

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

불행히도, 인터프리터가 현재 부사의 투영 (커링)을 지원하지 않기 때문에 이것은 oK에서 작동하지 않습니다. 실제 k5에서 작동합니다.

oK에서는 현재 정의를 람다로 감싸 야합니다.

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

4

J, 18 13 바이트

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

용법:

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

와우,이 작동합니다. 결막은 이상하다. 나는이 표현이 부사 (가능할 수 있음) 일 것으로 기대하지만 인수가 제시되면 함수이기도합니다.
randomra

3

apt , 24 바이트 25 33

저장된 9 7 바이트 @ETHproductions에 감사

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

ES6 파괴를 활용합니다.

온라인으로 사용해보십시오

Ungolfed && 설명

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]

Uo0에서 U까지의 숫자 범위를 생성하므로 Uo m@[V,W]=[V+W /2,(V*W q]작동해야합니다. (테스트되지 않음)
ETHproductions

아, 그리고 당신은 전혀 쉼표가 필요하지 않습니다. :)
ETHproductions

@ETHproductions 다시 한 번 감사드립니다! :)
Downgoat

오, 친애하는, 이것은 U1 이외의 다른 것에 대해 실패하고 , 각 루프를 진행하면서 출력합니다. 다음은 올바르게 작동하는 것입니다.Uo £[VW]=[V+W /2(V*W q]};[VW]
ETHproductions

@ETHproductions 감사합니다,하지만 사용 r도 일 듯
Downgoat

3

Matlab, 54 바이트

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

예:

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

3

피스, 12

u,.OG@*FG2EQ

테스트 스위트

설명

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

@.O에 대해 잊어 버렸지 만의 새로운 목적조차 몰랐습니다 E.
orlp

@ orlp 아, 귀하의 게시물을 보지 못했습니다, 내 나쁜 의견에 의견을 제안했을 것입니다. 그리고 그래, 변화하는 모든 것들을 추적하는 것은 약간의 투쟁이다 : P
FryAmTheEggman

2

Minkolang v0.14, 23 바이트

여기에서 보십시오 !

$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

파이썬 3, 65 55 바이트

lambda연산자를 사용하여 더 짧은 버전을 지적 해준 mathmandan에게 감사합니다 .

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

내 원래 버전 :

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

내 chagrin에게 재귀 함수 (JavaScript 및 C ++ 답변)는 간단한 for 루프보다 짧았습니다.


2
당신은 이것을 lambda삼항 if/else연산자 로 조금 줄일 수 있습니다 :f=lambda a,b,n:f((a+b)/2,(a*b)**.5,n-1)if n else(a,b)
mathmandan

문제 없어! (또한 이것은 53 바이트라고 생각합니다.)
mathmandan

내가 저장 한 .py 파일은 55 바이트로 표시됩니다. 프로그램 크기를 계산하는 더 좋은 방법이 있습니까?
잭 Brounstein

때때로이 사이트의 사람들은 코드를 mothereff.in/byte-counter에 복사하여 붙여 넣습니다 . 불일치가 궁금하다면 Windows가 .py 파일 끝에 불필요한 줄 바꿈 문자를 삽입하고 있다고 생각합니다 (Windows는 줄 바꿈을 1 대신 2 바이트로 계산합니다). 어느 쪽이든 점수 매기기 목적으로 마지막 개행을 코드의 일부로 계산할 필요는 없습니다. 여러 줄 항목을 게시하는 경우 마지막 줄 줄 끝에 줄 바꿈을 포함하지 않고 2 줄이 아닌 각 줄 바꿈 문자에 대해 1을 계산해야합니다. (어쨌든 규칙을 이해하는 한!)
mathmandan

2

R, 66 바이트

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

용법:

> 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

함수 이름을 제거하여 2 바이트를 저장할 수 있습니다.
Alex A.

2

Mathematica, 31 30 바이트

Martin Büttner 덕분에 1 바이트를 절약했습니다.

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

용법:

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

Out[1]= {13.4582, 13.4582}

1

루아, 62 바이트

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

용도에서 줄 인수를 명령 ...에 할당 n, a그리고 b, 나는 최근에 루아에 대해 알게 멋진 트릭.


1

하스켈, 40 바이트

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

익명의 기능. 사용법 예 :

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

람다 함수 (\(a,b)->((a+b)/2,sqrt$a*b))는 튜플에서 산술 및 기하 평균을 취합니다. 이는 첫 번째 입력 (튜플)부터 반복 된 다음 (!!)두 번째 입력을 인덱싱하여 반복 횟수를 지정합니다.


1

펄, 60 바이트

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

NB :이 메타 포스트 , 나는 믿는다 나는 점수가 올바른있어. 실제 코드 (작은 따옴표 사이)는 58 자입니다. a그리고 p가장 짧은 호출과의 차이로 +2를 추가 하고 플래그를 추가했습니다 .perl -e'...'

모호한 불만

나는 분명한 개선이 빠진 잔소리가 있습니다. "골프를 환영합니다"라는 것을 알고 있지만 평소보다 더 많은 합니다. 합니다.

초기에 나는 $\약간의 성공으로 두 번째 용어 로 사용하는 것에 혼란을 겪었 지만 위의 접근법은 추가로 2 바이트 더 짧아졌습니다.ap 필요한 플래그가 졌습니다. 마찬가지로 명시 적 $_할당을 피하는 것이 좋지만 루프가 어렵습니다.

shift@F버그 나도; 그래도 그렇게하지 않으면 (또는 사용하십시오.@F=(0,...,...) 바이트를 저장하지 않는 대신 ) @F할당에 오류가 있습니다.

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

출력

13.4581714817256 13.4581714817256

1

줄리아, 49 바이트

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

매우 직접적인 반복 알고리즘. 은 Using 기호와 여러 반환하는 것은 몇 바이트를 저장하지만 루프에 대한 구문은 몇 비용이 든다.


1

하스켈, 47 바이트

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

f를 사용하여 ab를 몇 바이트로 절약 할 수 있습니다. fx 0 = x; f (a, b) n = f ((a + b) / 2, sqrt $ a * b) $ n-1
Damien

그리고 함수 접두사를 정의하십시오.
xnor

1

줄리아, 42 바이트

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

이것은 재귀 함수입니다 f세 개의 숫자를 받아들이고 튜플을 반환 입니다.

언 골프 드 :

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

파이썬 2, 62 61 62 바이트

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

3
프로그램은 종료 될 때 한 번만 인쇄해야합니다.
lirtosiast

1
내 오해 결정된.
wflynny

1

CJam, 16 바이트

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

이것은 익명의 기능입니다. 입력은 두 개의 값 (두 배)과 반복 횟수가있는 목록입니다. 온라인으로 사용해보십시오테스트를 위해 I / O 코드를 사용 으로 .

@PeterTaylor가 질문을보기 전에 똑같이 긴 CJam 답변을 게시했기 때문에 일반적으로 이것을 게시하지 않았을 것입니다. 그러나 이것이 시리즈의 시작으로 알려지기 때문에 시리즈가 흥미있는 경우 옵션을 열어두기를 원했습니다.

길이는 Peter의 대답과 동일하지만 코드는 다릅니다. Peter가 별도의 값을 사용한 목록에서 두 값을 가져 와서 다른 입력 형식을 선택했습니다. 따라서 두 가지 입력 형식 중 많은 것이 없지만 코드는 매우 다르게 보입니다.

{     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

펄 6 ,  53  47 바이트

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

용법:

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

입력을에서 a,b,n로 변경하면 (a,b),n몇 바이트를 절약 할 수 있습니다.

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

용법:

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
}

실제로 ... *with를 바꾸면 매개 변수 ... -> (\a,\b) { a =~= b }가 필요하지 않습니다 $^n.
( ==대신 사용 하지 =~=마십시오. 멈추지 않을 수도 있습니다)

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

프롤로그, 80 바이트

암호:

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

예:

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

여기에서 온라인으로 사용해보십시오


0

자바, 103 96 84 바이트

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

모든 테스트 케이스를 확인하십시오.

이전 버전 (96 바이트) :

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

이전 버전 (103 바이트) :

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;}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.