AGMシリーズの穴1:算術幾何学的平均の計算


26

この質問は、このHNQに触発されました

シリーズについて

この質問は、AGMメソッドに関するシリーズの一部になりました。シリーズのこの最初の投稿は、実際に計算することについてですAGMます。これを他のコードゴルフチャレンジと同様に扱い、シリーズについてまったく心配することなく答えることができます。ただし、すべての課題にリーダーボードがあります。

算術-幾何平均とは

2つの数の算術幾何平均は、算術平均幾何平均を繰り返して収束する数として定義されます。あなたの仕事は、いくつかのn反復の後にこの数を見つけることです。

明確化

  • あなたは3つの数字を取ります a, b, n妥当な形式のします。
  • 以下のためnの反復、の算術と幾何平均を取るabしてにそれらを設定aし、b
  • 2つの数値abについて、算術平均はと定義され(a + b) / 2ます。
  • 幾何平均はと定義され√(a * b)ます。
  • aそして、b互いに接近している必要があります。
  • 次に、との両方aを出力しbます。
  • フロートの不正確さなどを心配する必要はありません。
  • これはので、バイト単位の最短コードが勝ちです!

テストケース

[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
両方abまたはどちら」両方、またはどちらか?
ドアノブ

@Doorknob -_-その両方。
マルティセン

1
@xnor no。最後のテストケースを見てください。
マルティセン

5
シリーズのこの部分を作成すると、ある種の不幸な状況が発生します。これは非常に単純なので、ソリューションはすべて非常によく似ています。そして、既に使用されている言語で同様のソリューションを投稿することは、一般的に嫌われています。約2分でソリューションを作成しましたが、既に使用されている言語であり、同じ長さです。一般的な投稿のエチケットに従う場合、シリーズに参加することはできません。
レトコラディ

回答:



9

Dyalog APL22 21 15バイト

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

ab)を正しい引数として受け取り、nの入力を求めます:

(

  +.× 0.5と正しい引数の内積

, に続く

  ×.*⍨正しい引数の「ドットパワー」と0.5 *

)⍣⎕ 数値プロンプト時間を適用しました。

*「ドットパワー」はドット積に似ていますが、次のようにプラスと乗算の代わりに乗算とパワーを使用します。

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

ngnのおかげで-3バイト。


古いバージョン:

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

n左引数およびa b右引数として取ります。

⊢⍵RIGHTARGに
(... )⍣⍺再計算LEFTARG回の
(+/÷≢)集計で割っ合計
,が続く
.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⍣⍺⊢⍵あなたが専門的に使うイディオムは、または類似?
リルトシアスト

@ThomasKwaはいは、例えば参照Of⍣core⊢TREEmiserver.dyalog.com(ラインに大きな「D」とスクロールをクリックし、[266])。
アダム

7

TI-BASIC、22バイト

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

アルゴリズムが正確に言うことを行います。プロンプトからNを取り、AおよびBをAns 2要素リストとして取得します。

Nが0の場合、For(ループは完全にスキップされます。



6

MATLAB / Octave、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バイト節約できます。
脳のガイド

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方が短くなります。
レトコラディ

1
#include行のスペースを削除することもできます。
アレックス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で動作します。

現時点では、定義をラムダでラップする必要があります。

  {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

Japt、24バイト25 33

@ETHproductionsに感謝9 7バイトを保存

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

ES6の破壊を活用します。

オンラインで試す

アンゴルフ&&説明

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

ああ、これUは1以外では失敗し、各ループをそのまま出力します。正常に動作ここでの1: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

Pyth、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

Pythonの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)

残念なことに、再帰関数(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バイトとしてリストされています。プログラムサイズを計算するより良い方法はありますか?
ジャックブラウンスタイン

このサイトのユーザーは、コードをコピーしてmothereff.in/byte-counterに貼り付けることがあります。矛盾について疑問に思っているなら、Windowsは不要な改行文字を.pyファイルの最後に挿入していると推測します(そしてWindowsは改行を1ではなく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バイトを節約できます。
アレックスA.

2

Mathematica、31 30バイト

MartinBüttnerのおかげで1バイト節約できました。

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

使用法:

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

Out[1]= {13.4582, 13.4582}

1

Lua、62バイト

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

コマンドライン引数from ...を使用してnaおよびに割り当てbます。これは最近Luaについて学んだ気の利いたトリックです。


1

Haskell、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))は、タプルの算術平均と幾何平均を取ります。これは、最初の入力(タプル)から反復され、次に(!!)2番目の入力にインデックスを付けて反復回数を指定します。


1

Perl、60バイト

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

NB:パーこのメタポスト、私は信じている私が正しいのスコアを持っています。実際のコード(一重引用符の間)は58文字です。その後apが最短呼び出しとの違いであるフラグ。perl -e'...'

あいまいな苦情

私はこのしつこい感じがあり、明らかな改善を見逃しています。「ゴルフをコーディングすることを歓迎します」と知っていますが、私はいつもよりも多くを意味しますこれを短くする簡単な機会があると信じています。

早い段階で、$\2番目の用語として使用することに多少の成功を収めていましたが、上記のアプローチは、追加のapフラグが必要な場合でも、2バイト短くなりました。同様に、明示的な$_割り当てを避けることは良いことですが、ループがそれを難し​​くします。

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

Haskell、47バイト

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

abをfのカップルとしていくつかのバイトを保存できます: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 3つの数値を受け入れ、タプルを返すです。

ゴルフをしていない:

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
プログラムは、終了時に1回だけ印刷する必要があります。
リルトシアスト

1
私の誤解。一定。
wflynny

1

CJam、16バイト

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

これは匿名関数です。入力は、2つの値(double)のリストと、それに続く反復カウントです。オンラインで試すテスト用のI / Oコードで。

私は質問を見る前に@PeterTaylorが同じくらい長いCJamの回答を投稿したので、私は通常これを投稿しませんでした。しかし、これはシリーズの始まりとして宣伝されているので、シリーズが面白い場合に備えてオプションを開いたままにしておきたいと思いました。

長さはピーターの答えと同じですが、コードはそうではありません。リスト内の2つの値を取得することにより、異なる入力形式を選択しました。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

Perl 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

Java、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.