AGM-Serie Bohrung 1: Berechnen Sie den arithmetisch-geometrischen Mittelwert


26

Diese Frage wurde von diesem HNQ inspiriert .

Über die Serie

Diese Frage ist nun Teil einer Reihe zur AGM-Methode. In diesem ersten Beitrag der Reihe geht es um die Berechnung der AGM. Sie können dies wie jede andere Code-Golf-Herausforderung behandeln und beantworten, ohne sich Gedanken über die Serie zu machen. Es gibt jedoch eine Rangliste für alle Herausforderungen.

Was ist das arithmetisch-geometrische Mittel?

Der arithmetisch-geometrische Mittelwert zweier Zahlen ist definiert als die Zahl, zu der die arithmetischen und geometrischen Mittelwerte wiederholt konvergieren. Ihre Aufgabe ist es, diese Nummer nach einigen nIterationen zu finden.

Klarstellungen

  • Sie nehmen drei Zahlen a, b, nin jedem vernünftigen Format.
  • nNehmen Sie für Iterationen den arithmetischen und geometrischen Mittelwert von aund bund setzen Sie diese auf aund b.
  • Für zwei Zahlen aund bist das arithmetische Mittel definiert als (a + b) / 2.
  • Das geometrische Mittel ist definiert als √(a * b).
  • aund bsollten sich nähern.
  • Dann geben Sie beide aund aus b.
  • Sie müssen sich keine Gedanken über die Ungenauigkeit des Schwimmers machen.
  • Das ist also gewinnt der kürzeste Code in Bytes !

Testfälle

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

Bestenliste

Aus Martins Serie gestohlen.

Das folgende Snippet generiert eine Rangliste für alle Herausforderungen der Serie.

Um sicherzustellen, dass Ihre Antworten angezeigt werden, beginnen Sie jede Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:

# Language Name, N bytes

Wobei N die Größe Ihrer Einreichung ist. Wenn Sie Ihre Punktzahl verbessern, können Sie alte Punkte in der Überschrift behalten, indem Sie sie durchstreichen. Zum Beispiel:

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


1
Sind die Anfangszahlen positive ganze Zahlen?
xnor

2
" beides aoderb " - nun, welches? Beides oder beides?
Türklinke

@Doorknob -_- Es ist beides.
Maltysen

1
@xnor no. Schauen Sie sich den letzten Testfall an.
Maltysen

5
Dieser Teil einer Serie zu machen, verursacht eine Art unglückliche Situation. Dies ist so einfach, dass alle Lösungen sehr ähnlich aussehen werden. Das Posten ähnlicher Lösungen in bereits verwendeten Sprachen wird im Allgemeinen verpönt. Ich habe meine Lösung in ungefähr 2 Minuten geschrieben, aber sie ist in einer Sprache, die bereits verwendet wurde, und hat dieselbe Länge. Wenn ich mich an die typische Posting-Etikette halte, kann ich nicht an der Serie teilnehmen.
Reto Koradi

Antworten:



9

Dyalog APL , 22 21 15 Bytes

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

Nimmt ( a , b ) als rechtes Argument und fordert zur Eingabe von n auf :

(

  +.× Skalarprodukt von 0,5 und das richtige Argument

, gefolgt von

  ×.*⍨"Punktstärke" des richtigen Arguments und 0,5 *

)⍣⎕ verwendete numerische Eingabeaufforderungszeiten.

* "Punktleistung" ist wie Punktprodukt, verwendet jedoch Multiplikation und Potenz anstelle von Plus und Multiplikation wie folgt:

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

-3 Bytes dank ngn.


Alte Version:

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

Nimmt nals linkes Argument und a bals rechtes Argument.

⊢⍵Auf der rechten Seite
(... )⍣⍺berechnen Sie die LeftArg- Zeitsumme
(+/÷≢)geteilt durch die Summe
,gefolgt von
.5*⍨×/der Quadratwurzel des Produkts neu.

Alle Testfälle:

      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│
└────┴─────┴────────────────┴───────────────────────┴───────────────────────┴───────────────────────┘

Ist f⍣⍺⊢⍵oder ähnlich eine Redewendung, die Sie professionell verwenden?
Lirtosiast

Siehe @ThomasKwa Ja, zum Beispiel Of⍣core⊢TREEbei miserver.dyalog.com (klicken Sie auf den großen „D“ und navigieren Sie zu der Zeile [266]).
Adám

7

TI-BASIC, 22 Bytes

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

Tut genau das, was der Algorithmus sagt. Nimmt N von der Eingabeaufforderung und A und B Ansals Liste mit zwei Elementen durch.

Wenn N 0 ist, wird die For(Schleife vollständig übersprungen.


6

JavaScript ES7, 48 43 Bytes

-5 danke an Downgoat!

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

Sehr einfache rekursive Funktion.


2
(a*b)**.5ist kürzer als Math.sqrt(a*b). Beispiel
Downgoat

@ Downgoat Das ist ES7, aber meh.
Conor O'Brien

6

MATLAB / Octave, 69 65 Bytes

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

1
Sie können dies b=(a*b).^5direkt tun, da Sie bin dieser Iteration nicht mehr wiederverwenden und 4 Bytes sparen.
Brain Guider

6

Gelee, nicht konkurrierend

9 Bytes Diese Antwort ist nicht konkurrierend, da sie Funktionen verwendet, die die Herausforderung nachholen.

SH;P½¥ðṛ¡

Probieren Sie es online!

Wie es funktioniert

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

Im Ernst, 11 Bytes

,p`;π√@æk`n

Hex Dump:

2c70603be3fb40916b606e

Probieren Sie es online aus

Erläuterung:

,                    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 Bytes

Vielen Dank an @RetoKoradi und @AlexA, dass sie mir 6 Bytes gespart haben.

Dies ist nicht wettbewerbsfähig, da C ++ keine gute Golfsprache ist. Habe das zum Spaß gemacht :)

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

Dies ist eine einfache Rekursionsfunktion, die der JS-Antwort sehr ähnlich ist.


3
Sie können die Leerzeichen nach den Kommas entfernen. Außerdem ist die Verwendung von floatanstelle von doublekürzer.
Reto Koradi

1
Sie können auch das Leerzeichen in der #includeZeile entfernen .
Alex A.

Wow, ich bin dumm, das nicht zu bemerken. Vielen Dank!
TheCoffeeCup

Ich würde überlegen, f(float*s)welcher Zeiger auf 3 Floats ein "vernünftiges Format" hat. Ich bin mir nicht sicher, ob es dadurch tatsächlich kürzer wird.
NWP

4

K5, 15 Bytes

Sehr wörtlich:

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

In Aktion:

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

Leider funktioniert dies in OK nicht, da dieser Interpreter derzeit keine Projektion (Currying) von Adverbien unterstützt. Funktioniert im echten k5.

In oK müsste die Definition derzeit in ein Lambda eingeschlossen werden:

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

4

J, 18 13 Bytes

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

Verwendung:

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

Wow, das funktioniert. Konjunktionen sind komisch. Ich würde erwarten, dass dieser Ausdruck ein Adverb ist (was es auch sein kann), aber wenn er mit Argumenten präsentiert wird, ist er auch eine Funktion.
Randomra

3

Japt , 24 Bytes 25 33

9 7 Bytes dank @ETHproductions gespeichert

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

Nutzt die Vorteile der ES6-Destrukturierung.

Probieren Sie es online aus

Ungolfed && Erklärung

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]

Uogeneriert einen Zahlenbereich von 0 bis U, Uo m@[V,W]=[V+W /2,(V*W q]sollte also funktionieren. (Ungetestet)
ETHproductions

Oh, und Sie sollten die Kommas überhaupt nicht brauchen. :)
ETHproductions

@ETHproductions nochmals vielen Dank! :)
Downgoat

Oh je, dies schlägt für jeden Uanderen als 1 fehl und gibt jede Schleife so wie sie ist aus. Hier ist eine, die richtig funktioniert:Uo £[VW]=[V+W /2(V*W q]};[VW]
ETHproductions

@ETHproductions danke, aber mit rschien auch zu funktionieren
Downgoat

3

Matlab, 54 Bytes

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

Beispiel:

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

3

Pyth, 12

u,.OG@*FG2EQ

Test Suite

Erläuterung

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

Vergaß @und .O, aber ich wusste nicht einmal den neuen Zweck von E.
Orlp

@orlp ah, hab deinen Beitrag nicht gesehen, meine schlechte, ich hätte das nur in den Kommentaren vorgeschlagen. Und ja, all die Änderungen im
Auge zu behalten,

2

Minkolang v0.14, 23 Bytes

Probieren Sie es hier aus !

$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 Bytes

Vielen Dank an mathmandan, der mithilfe des lambdaOperators auf eine kürzere Version hingewiesen hat .

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

Meine ursprüngliche Version:

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

Zu meinem Leidwesen war eine rekursive Funktion (a la JavaScript und C ++ Antworten) kürzer als eine einfache for-Schleife.


2
Sie können dies mit lambdaund dem ternären if/elseOperator ein wenig verkürzen :f=lambda a,b,n:f((a+b)/2,(a*b)**.5,n-1)if n else(a,b)
mathmandan

Kein Problem! (Ich denke auch, das sind 53 Bytes.)
Mathmandan

Die von mir gespeicherte .py-Datei ist mit 55 Byte angegeben. Gibt es eine bessere Möglichkeit, die Programmgröße zu berechnen?
Jack Brounstein

Manchmal kopieren Leute auf dieser Site ihren Code und fügen ihn ein mothereff.in/byte-counter ein . Wenn Sie sich über die Diskrepanz wundern, würde ich vermuten, dass Windows am Ende Ihrer .py-Datei ein unnötiges Newline-Zeichen einfügt (und Windows zählt eine Newline als 2 Bytes anstelle von 1). In beiden Fällen müssen Sie diese letzte Zeile nicht als Teil Ihres Codes für Bewertungszwecke zählen. Wenn Sie einen mehrzeiligen Eintrag veröffentlichen, sollten Sie für jedes Zeilenumbruchzeichen 1 zählen, nicht 2, und am Ende Ihrer letzten Codezeile keinen Zeilenumbruch einfügen. (Soweit ich die Regeln überhaupt verstehe!)
Mathmandan

2

R, 66 Bytes

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

Verwendung:

> 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

Sie können den Funktionsnamen entfernen, um 2 Bytes zu sparen.
Alex A.

2

Mathematica, 31-30 Bytes

Ein Byte gespart dank Martin Büttner.

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

Verwendung:

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

Out[1]= {13.4582, 13.4582}

1

Lua, 62 Bytes

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

Verwendet Befehlszeilenargumente von ..., um und einen raffinierten Trick zuzuweisen n, den ich kürzlich über Lua gelernt habe.ab


1

Haskell, 40 Bytes

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

Eine anonyme Funktion. Anwendungsbeispiel:

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

Die Lambda-Funktion (\(a,b)->((a+b)/2,sqrt$a*b))berechnet den arithmetischen und geometrischen Mittelwert eines Tupels. Dies wird beginnend mit der ersten Eingabe (einem Tupel) iteriert und anschließend (!!)die zweite Eingabe indiziert, um die Anzahl der Iterationen anzugeben.


1

Perl, 60 Bytes

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

NB: Nach diesem Meta-Post , glaube ich ich das Scoring richtig haben. Der tatsächliche Code (zwischen einfachen Anführungszeichen) besteht aus 58 Zeichen. Dann habe ich +2 für aund pflags hinzugefügt , da dies der Unterschied zum kürzesten Aufruf ist.perl -e'...'

Vage Beschwerden

Ich habe das quälende Gefühl, dass mir eine offensichtliche Verbesserung fehlt. Ich weiß, "Willkommen beim Code Golf", aber ich meine mehr als üblich ich glaube, es gibt eine einfache Möglichkeit, dies zu verkürzen.

Schon früh hatte ich $\mit einigem Erfolg daran herumgespielt, als zweiten Term zu verwenden, aber der obige Ansatz endete damit, dass er 2 Bytes kürzer war, obwohl die zusätzlichen apFlags erforderlich waren. Ebenso das explizite vermeiden$_ wäre es schön, Zuweisung zu , aber die Schleife erschwert dies.

Das shift@Fnervt mich auch; Wenn ich es jedoch nicht so mache (oder @F=(0,...,...)stattdessen verwende, wodurch keine Bytes gespart werden), liegt ein Fehler von eins zu eins vor@F Zuweisung vor.

Beispiel

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

Ausgänge

13.4581714817256 13.4581714817256

1

Julia, 49 Bytes

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

Ziemlich direkter iterativer Algorithmus. Die Verwendung des Symbols und der Mehrfachrückgabe spart einige Bytes, die for-Schleifensyntax jedoch einige.


1

Haskell, 47 Bytes

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

Sie könnten einige Bytes speichern, indem Sie ab als Paar in f nehmen: fx 0 = x; f (a, b) n = f ((a + b) / 2, sqrt $ a * b) $ n-1
Damien

Und definieren Sie das Funktions-Infix.
xnor

1

Julia, 42 Bytes

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

Dies ist eine rekursive Funktion f, die drei Zahlen akzeptiert und ein Tupel zurückgibt.

Ungolfed:

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-Grundelemente

Primitive wurden gemäß diesem Metapost gezählt .

ziemlich ehrlich, nicht viel zu erklären.


1

Python 2, 62 61 62 Bytes

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

3
Das Programm sollte nur einmal gedruckt werden, wenn es beendet wird.
Lirtosiast

1
Mein Missverständnis. Fest.
wflynny

1

CJam, 16 Bytes

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

Dies ist eine anonyme Funktion. Die Eingabe ist eine Liste mit den beiden Werten (als Doppel), gefolgt von der Iterationszahl. Probieren Sie es online aus mit E / A-Code zum Testen aus.

Normalerweise hätte ich das nicht gepostet, weil @PeterTaylor eine ebenso lange CJam-Antwort gepostet hat, bevor ich die Frage sah. Da dies jedoch als Beginn einer Serie beworben wird, wollte ich meine Optionen offen halten, falls die Serie interessant ist.

Die Länge entspricht der Antwort von Peter, der Code jedoch nicht. Ich habe ein anderes Eingabeformat gewählt, indem ich die beiden Werte in eine Liste aufgenommen habe, in der Peter separate Werte verwendet hat. Obwohl es bei beiden Eingabeformaten nicht viel zu tun gibt, sieht der Code ganz anders aus.

{     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 Bytes

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

Verwendung:

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

Wenn ich die Eingabe von a,b,nauf ändere , (a,b),nkann ich ein paar Bytes sparen.

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

Verwendung:

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
}

Wirklich würde ich die Swap ... *mit ... -> (\a,\b) { a =~= b }, dann gäbe es keine Notwendigkeit für den seinen $^nParameter.
(nicht ==anstelle von verwenden =~=, oder es kann nicht aufhören)

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 Bytes

Code:

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

Beispiel:

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

Probieren Sie es hier online aus


0

Java, 103 96 84 Bytes

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

Überprüfen Sie alle Testfälle.

Alte Version (96 Bytes):

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

Alte Version (103 Bytes):

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;}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.