AGM, trou 1: calcul de la moyenne arithmétique et géométrique


26

Cette question a été inspirée par ce HNQ .

À propos de la série

Cette question fait maintenant partie d'une série sur la méthode AGM. Ce premier article de la série portera sur le calcul réel de laAGM . Vous pouvez traiter cela comme n'importe quel autre défi de golf de code et y répondre sans vous soucier de la série. Cependant, il existe un classement pour tous les défis.

Quelle est la moyenne arithmétique – géométrique

La moyenne arithmétique – géométrique de deux nombres est définie comme le nombre vers lequel convergent les moyennes arithmétiques et géométriques. Votre tâche consiste à trouver ce numéro après quelques nitérations.

Clarifications

  • Vous prenez trois nombres, a, b, ndans n'importe quel format raisonnable.
  • Pour les nitérations, prenez la moyenne arithmétique et géométrique de aet bet définissez-les sur aet b.
  • Pour deux nombres aet b, la moyenne arithmétique est définie comme(a + b) / 2 .
  • La moyenne géométrique est définie comme √(a * b).
  • aet bdevraient se rapprocher.
  • Ensuite, sortez les deux aet b.
  • Vous n'avez pas à vous soucier de l'imprécision du flotteur et autres.
  • C'est le donc le code le plus court en octets gagne!

Cas de test

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

Classement

Volé de la série de Martin.

L'extrait suivant générera un classement de tous les défis de la série.

Pour vous assurer que vos réponses s'affichent, veuillez commencer chaque réponse par un titre, en utilisant le modèle Markdown suivant:

# Language Name, N bytes

où N est la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores dans le titre, en les barrant. Par exemple:

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


1
Les nombres initiaux sont-ils des entiers positifs?
2015

2
"les deux aoub " -bien, lequel? Les deux ou l'un ou l'autre?
Poignée de porte

@Doorknob -_- Ses deux.
Maltysen

1
@xnor no. Regardez le dernier cas de test.
Maltysen

5
Faire cette partie d'une série provoque une sorte de situation malheureuse. C'est tellement simple que les solutions vont toutes se ressembler. Et publier des solutions similaires dans des langues déjà utilisées est généralement mal vu. J'ai écrit ma solution en environ 2 minutes, mais c'est dans une langue qui était déjà utilisée, et c'est la même longueur. Si je respecte l'étiquette de publication typique, je ne pourrai pas participer à la série.
Reto Koradi

Réponses:



9

Dyalog APL , 22 21 15 octets

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

Prend ( a , b ) comme argument de droite et demande n :

(

  +.× produit scalaire de 0,5 et le bon argument

, suivi par

  ×.*⍨"puissance des points" de l'argument de droite et 0,5 *

)⍣⎕ temps d'invite numérique appliqués.

* "dot power" est comme un produit scalaire, mais en utilisant la multiplication et la puissance au lieu de plus et la multiplication, comme suit:

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

-3 octets grâce à ngn.


Ancienne version:

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

Prend ncomme argument de gauche et a bcomme argument de droite.

⊢⍵Sur le RightArg
(... )⍣⍺recalculez le LeftArg fois la
(+/÷≢)somme divisée par le décompte
,suivi de
.5*⍨×/la racine carrée du produit.

Tous les cas de test:

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

Est-ce f⍣⍺⊢⍵ou un idiome similaire que vous utilisez professionnellement?
lirtosiast

@ThomasKwa Oui, voir par exemple Of⍣core⊢TREEsur miserver.dyalog.com (cliquez sur le grand "D" et faites défiler jusqu'à la ligne [266]).
2015

7

TI-BASIC, 22 octets

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

Fait exactement ce que dit l'algorithme. Prend N de l'invite, et A et B jusqu'à Ansune liste à deux éléments.

Si N est 0, la For(boucle est entièrement ignorée.


6

JavaScript ES7, 48 43 octets

-5 grâce à Downgoat!

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

Fonction récursive très simple.


2
(a*b)**.5est plus court que Math.sqrt(a*b). exemple
Downgoat

@Downgoat C'est ES7, mais meh.
Conor O'Brien

6

MATLAB / Octave, 69 65 octets

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

1
Vous pouvez le faire b=(a*b).^5directement car vous ne réutilisez pas à bnouveau dans cette itération et enregistrer 4 octets.
Brain Guider

6

Gelée, non compétitive

9 octets Cette réponse n'est pas concurrente, car elle utilise des fonctionnalités postérieures au défi.

SH;P½¥ðṛ¡

Essayez-le en ligne!

Comment ça marche

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

Sérieusement, 11 octets

,p`;π√@æk`n

Vidage hexadécimal:

2c70603be3fb40916b606e

Essayez-le en ligne

Explication:

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

Merci à @RetoKoradi et @AlexA de m'avoir économisé 6 octets.

Ce n'est pas compétitif, car C ++ n'est pas un bon langage de golf. J'ai fait ça pour le plaisir :)

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

Il s'agit d'une fonction de récursivité simple, très similaire à la réponse JS.


3
Vous pouvez vous débarrasser des espaces après les virgules. En outre, l'utilisation floatau lieu de doubleest plus courte.
Reto Koradi

1
Vous pouvez également supprimer l'espace dans la #includeligne.
Alex A.

Wow, je suis stupide de ne pas le remarquer. Merci!
TheCoffeeCup

Je considérerais f(float*s)qui prend un pointeur sur 3 flotteurs dans un "format raisonnable". Je ne sais pas si cela le raccourcit réellement.
nwp

4

K5, 15 octets

Très littéral:

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

En action:

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

Malheureusement, cela ne fonctionne pas dans oK car cet interprète ne prend pas actuellement en charge la projection (curry) des adverbes. Fonctionne dans le vrai k5.

En ok, il faudrait actuellement envelopper la définition dans un lambda:

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

4

J, 18 13 octets

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

Usage:

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

Wow, cela fonctionne. Les conjonctions sont étranges. Je m'attendrais à ce que cette expression soit un adverbe (ce qu'elle peut être), mais si elle est présentée avec des arguments, c'est aussi une fonction.
randomra

3

Japt , 24 octets 25 33

Enregistré 9 7 octets grâce à @ETHproductions

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

Profite de la déstructuration ES6.

Essayez-le en ligne

Ungolfed && Explication

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]

Uogénère une plage de nombres de 0 à U, donc Uo m@[V,W]=[V+W /2,(V*W q]devrait fonctionner. (Non testé)
ETHproductions

Oh, et vous ne devriez pas du tout avoir besoin de virgules. :)
ETHproductions

@ETHproductions encore merci! :)
Downgoat

Oh mon cher, cela échoue pour tout Uautre que 1, produisant chaque boucle au fur et à mesure. En voici une qui fonctionne correctement:Uo £[VW]=[V+W /2(V*W q]};[VW]
ETHproductions

@ETHproductions merci, mais l'utilisation rsemble fonctionner aussi
Downgoat

3

Matlab, 54 octets

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

Exemple:

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

3

Pyth, 12

u,.OG@*FG2EQ

Suite de tests

Explication

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

J'ai oublié @et .O, mais je ne connaissais même pas le nouveau but de E.
orlp

@orlp ah, vous n'avez pas vu votre message, mon mauvais, je l'aurais simplement suggéré dans les commentaires. Et oui, garder une trace de tout ce qui change est un peu difficile: P
FryAmTheEggman

2

Minkolang v0.14, 23 octets

Essayez-le ici !

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

Merci à mathmandan d'avoir indiqué une version plus courte en utilisant le lambda opérateur.

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

Ma version originale:

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

À mon grand regret, une fonction récursive (à la manière des réponses JavaScript et C ++) était plus courte qu'une simple boucle for.


2
Vous pouvez raccourcir un peu ceci avec lambdal' if/elseopérateur ternaire :f=lambda a,b,n:f((a+b)/2,(a*b)**.5,n-1)if n else(a,b)
mathmandan

Aucun problème! (Aussi, je pense que cela fait 53 octets.)
mathmandan

Le fichier .py que j'ai enregistré est répertorié comme étant de 55 octets. Existe-t-il une meilleure façon de calculer la taille du programme?
Jack Brounstein

Parfois, les gens sur ce site copient et collent leur code dans mothereff.in/byte-counter . Si vous vous interrogez sur la différence, je suppose que Windows insère un caractère de nouvelle ligne inutile à la fin de votre fichier .py (et Windows compte une nouvelle ligne comme 2 octets au lieu de 1). Quoi qu'il en soit, vous n'avez pas à compter cette dernière nouvelle ligne dans votre code à des fins de notation. Si vous publiez une entrée sur plusieurs lignes, vous devez compter 1 pour chaque caractère de nouvelle ligne, pas 2, et n'incluant aucune nouvelle ligne à la fin de votre dernière ligne de code. (Pour autant que je comprends les règles de toute façon!)
mathmandan

2

R, 66 octets

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

Usage:

> 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

Vous pouvez supprimer le nom de la fonction pour enregistrer 2 octets.
Alex A.

2

Mathematica, 31 30 octets

Un octet enregistré grâce à Martin Büttner.

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

Usage:

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

Out[1]= {13.4582, 13.4582}

1

Lua, 62 octets

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

Utilise les arguments de ligne de commande de ...pour attribuer à n, aet b, astuce astucieuse que j'ai apprise sur Lua récemment.


1

Haskell, 40 octets

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

Une fonction anonyme. Exemple d'utilisation:

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

La fonction lambda (\(a,b)->((a+b)/2,sqrt$a*b))prend la moyenne arithmétique et géométrique sur un tuple. Il est itéré en commençant par la première entrée (un tuple), puis (!!)indexe la deuxième entrée pour spécifier le nombre d'itérations.


1

Perl, 60 octets

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

NB: Par ce meta post , je crois que j'ai le bon score. Le code réel (entre guillemets simples) est de 58 caractères, puis j'ai ajouté +2 pour aetp drapeaux car c'est la différence par rapport à l'invocation la plus courte,perl -e'...'

Plaintes vagues

J'ai ce sentiment persistant que je manque une amélioration évidente. Je sais, "bienvenue au golf de code", mais je veux dire plus que d'habitude je crois qu'il y a une occasion facile de raccourcir cela.

Au début, j'avais déconseillé d'utiliser $\le deuxième terme avec un certain succès, mais l'approche ci-dessus a fini par être 2 octets plus courte, même avec les apdrapeaux supplémentaires requis. De même, éviter l' $_affectation explicite serait bien, mais la boucle rend cela difficile.

Les shift@Finsectes me dérangent aussi; si je ne le fais pas de cette façon, (ou que j'utilise à la @F=(0,...,...)place, ce qui ne sauve pas d'octets), il y a une erreur de coup par coup avec le@F affectation.

Exemple

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

Les sorties

13.4581714817256 13.4581714817256

1

Julia, 49 octets

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

Algorithme itératif assez direct. L'utilisation du symbole et du retour multiple économise quelques octets, mais la syntaxe de la boucle for en coûte quelques-uns.


1

Haskell, 47 octets

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

vous pouvez enregistrer quelques octets en prenant ab comme couple dans f: fx 0 = x; f (a, b) n = f ((a + b) / 2, sqrt $ a * b) $ n-1
Damien

Et définissez l'infixe de la fonction.
xnor

1

Julia, 42 octets

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

Il s'agit d'une fonction récursive fqui accepte trois nombres et renvoie un tuple.

Non golfé:

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

Python 2, 62 61 62 octets

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

3
Le programme ne doit imprimer qu'une seule fois, lorsqu'il se termine.
lirtosiast

1
Mon malentendu. Fixé.
wflynny

1

CJam, 16 octets

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

Il s'agit d'une fonction anonyme. L'entrée est une liste avec les deux valeurs (en double), suivie du nombre d'itérations. Essayez-le en ligne avec du code d'E / S pour le tester.

Je n'aurais pas normalement posté cela parce que @PeterTaylor a posté une réponse CJam tout aussi longue avant de voir la question. Mais comme cela est annoncé comme le début d'une série, je voulais garder mes options ouvertes au cas où la série serait intéressante.

Bien que la longueur soit la même que la réponse de Peter, le code ne l'est pas. J'ai choisi un format d'entrée différent en prenant les deux valeurs dans une liste, où Peter a utilisé des valeurs distinctes. Donc, même s'il n'y a pas grand-chose avec l'un ou l'autre des formats d'entrée, le code semble très différent.

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

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

usage:

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

Si je change l'entrée de a,b,nà(a,b),n je peux économiser quelques octets.

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

usage:

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
}

Vraiment, j'échangerais le ... *avec ... -> (\a,\b) { a =~= b }, alors il n'y aurait pas besoin du $^nparamètre.
(ne pas utiliser à la ==place de =~=, ou il peut ne pas s'arrêter)

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 octets

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

Exemple:

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

Essayez-le en ligne ici


0

Java, 103 96 84 octets

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

Vérifiez tous les cas de test.

Ancienne version (96 octets):

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

Ancienne version (103 octets):

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;}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.