Serie AGM Hoyo 1: Calcular la media aritmética-geométrica

26

Esta pregunta fue inspirada por este HNQ .

Sobre la serie

Esta pregunta ahora es parte de una serie sobre el método AGM. Esta primera publicación de la serie tratará sobre el cálculo real AGM. Puede tratar esto como cualquier otro desafío de código de golf y responderlo sin preocuparse por la serie. Sin embargo, hay una tabla de clasificación en todos los desafíos.

¿Qué es la media aritmética-geométrica?

La media aritmética-geométrica de dos números se define como el número al que convergen repetidamente los medios aritméticos y geométricos. Su tarea es encontrar este número después de algunas niteraciones.

Aclaraciones

  • Toma tres números, a, b, nen cualquier formato razonable.
  • Para niteraciones, tomar la media aritmética y geométrica de ay by establecer aquellos a ay b.
  • Para dos números ay b, la media aritmética se define como (a + b) / 2.
  • La media geométrica se define como √(a * b).
  • ay bdeberían acercarse el uno al otro.
  • Entonces, salida ambos ay b.
  • No tiene que preocuparse por la imprecisión del flotador y demás.
  • Este es el código más corto en bytes gana!

Casos de prueba

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

Tabla de clasificación

Robado de la serie de Martin.

El siguiente fragmento generará una tabla de clasificación en todos los desafíos de la serie.

Para asegurarse de que sus respuestas aparezcan, comience cada respuesta con un título, utilizando la siguiente plantilla de Markdown:

# Language Name, N bytes

donde N es el tamaño de su envío. Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

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

Maltysen
fuente
1
¿Son los números iniciales enteros positivos?
xnor
2
" ambos aob ", ¿cuál? ¿Ambos o uno de los dos?
Pomo de la puerta
@Doorknob -_- Son ambos.
Maltysen
1
@xnor no. Mira el último caso de prueba.
Maltysen
55
Hacer esta parte de una serie provoca una especie de situación desafortunada. Esto es tan simple que todas las soluciones se verán bastante similares. Y publicar soluciones similares en idiomas que ya se usaban generalmente está mal visto. Escribí mi solución en aproximadamente 2 minutos, pero está en un idioma que ya se usó y tiene la misma duración. Si sigo la etiqueta típica de publicación, no podré participar en la serie.
Reto Koradi

Respuestas:

9

Dyalog APL , 22 21 15 bytes

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

Toma ( a , b ) como argumento correcto y solicita n :

(

  +.× producto punto de 0.5 y el argumento correcto

, seguido por

  ×.*⍨"punto de poder" del argumento correcto y 0.5 *

)⍣⎕ tiempos de solicitud numéricos aplicados.

* "dot power" es como un producto dot, pero usa multiplicación y potencia en lugar de más y multiplicación, de la siguiente manera:

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

-3 bytes gracias a ngn.


Versión antigua:

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

Toma ncomo argumento izquierdo y a bcomo argumento derecho.

⊢⍵En el RightArg
(... )⍣⍺recalcule la
(+/÷≢)suma de veces LeftArg dividida por el recuento
,seguido por
.5*⍨×/la raíz cuadrada del producto.

Todos los casos de prueba:

      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│
└────┴─────┴────────────────┴───────────────────────┴───────────────────────┴───────────────────────┘
Adán
fuente
¿Es f⍣⍺⊢⍵o similar un idioma que utilizas profesionalmente?
lirtosiast el
@ThomasKwa Sí, consulte, por ejemplo, Of⍣core⊢TREEen miserver.dyalog.com (haga clic en la "D" grande y desplácese hasta la línea [266]).
Adám
7

TI-BASIC, 22 bytes

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

Hace exactamente lo que dice el algoritmo. Toma N del indicador y A y B Anscomo una lista de dos elementos.

Si N es 0, el For(bucle se omite por completo.

lirtosiast
fuente
6

JavaScript ES7, 48 43 bytes

-5 gracias a Downgoat!

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

Función recursiva muy simple.

Conor O'Brien
fuente
2
(a*b)**.5es más corto que Math.sqrt(a*b). ejemplo
Downgoat
@Downgoat Eso es ES7, pero 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
costrom
fuente
1
Puede hacerlo b=(a*b).^5directamente ya que no está reutilizando bnuevamente en esa iteración y guardar 4 bytes.
Brain Guider
6

Gelatina, no competidora

9 bytes Esta respuesta no es competitiva, ya que utiliza características que son posteriores al desafío.

SH;P½¥ðṛ¡

Pruébalo en línea!

Cómo funciona

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.
Dennis
fuente
5

En serio, 11 bytes

,p`;π√@æk`n

Hex Dump:

2c70603be3fb40916b606e

Pruébalo en línea

Explicación:

,                    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.
quintapia
fuente
5

C ++, 108 102 100 bytes

Gracias a @RetoKoradi y @AlexA por guardarme 6 bytes.

Esto no es competitivo, porque C ++ no es un buen lenguaje de golf. Hice esto por diversión :)

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

Esta es una función de recursión simple, muy similar a la respuesta JS.

TheCoffeeCup
fuente
3
Puedes deshacerte de los espacios después de las comas. Además, usar en floatlugar de doublees más corto.
Reto Koradi
1
También puede eliminar el espacio en la #includelínea.
Alex A.
Wow, soy estúpido por no notar eso. ¡Gracias!
TheCoffeeCup
Consideraría f(float*s)que lleva un puntero a 3 flotantes en un "formato razonable". No estoy seguro si eso realmente lo hace más corto.
nwp
4

K5, 15 bytes

Muy literal:

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

En acción:

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

Desafortunadamente, esto no funciona en OK porque ese intérprete no admite actualmente la proyección (currículum) de adverbios. Funciona en el real k5.

En OK, actualmente sería necesario ajustar la definición en una lambda:

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

J, 18 13 bytes

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

Uso:

   agm =: -:@+/,%:@*/^:
   5 agm 24 6
13.4582 13.4582
alephalpha
fuente
Wow, esto funciona. Las conjunciones son raras. Esperaría que esta expresión sea un adverbio (que puede ser), pero si se presenta con argumentos, también es una función.
randomra
3

Japt , 24 bytes 25 33

Guardado 9 7 bytes gracias a @ETHproductions

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

Aprovecha la desestructuración de ES6.

Pruébalo en línea

Ungolfed && Explicación

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]
Downgoat
fuente
Uogenera un rango de números de 0 a U, por lo que Uo m@[V,W]=[V+W /2,(V*W q]debería funcionar. (No probado)
ETHproductions
Ah, y no deberías necesitar las comas en absoluto. :)
ETHproductions
@ETHproductions gracias una vez más! :)
Downgoat
Oh querido, esto falla para cualquier Uotro que no sea 1, generando cada ciclo a medida que avanza. Aquí hay uno que funciona correctamente:Uo £[VW]=[V+W /2(V*W q]};[VW]
ETHproductions
@ETHproductions gracias, pero el uso también rparecía funcionar
Downgoat
3

Matlab, 54 bytes

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

Ejemplo:

>> f([24 6], 2)
ans =
  13.500000000000000  13.416407864998739
Luis Mendo
fuente
3

Pyth, 12

u,.OG@*FG2EQ

Banco de pruebas

Explicación

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
FryAmTheEggman
fuente
Olvidé @y .O, pero ni siquiera sabía el nuevo propósito de E.
orlp
@orlp ah, no vi tu publicación, lo malo que hubiera sugerido es esto en los comentarios. Y sí, hacer un seguimiento de todas las cosas cambiantes es un poco
difícil
2

Minkolang v0.14, 23 bytes

Pruébalo aquí !

$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
Conor O'Brien
fuente
2

Pyth, 15 bytes

u,^*FG.5csG2vzQ
orlp
fuente
2

Python 3, 65 55 bytes

Gracias a Mathmandan por señalar una versión más corta usando el lambdaoperador

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

Mi versión original:

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

Para mi disgusto, una función recursiva (como las respuestas de JavaScript y C ++) era más corta que un simple bucle for.

Jack Brounstein
fuente
2
Puede acortar esto un poco con lambday el if/elseoperador ternario :f=lambda a,b,n:f((a+b)/2,(a*b)**.5,n-1)if n else(a,b)
mathmandan
¡No hay problema! (Además, creo que esto es 53 bytes.)
Mathmandan
El archivo .py que he guardado aparece como 55 bytes. ¿Hay una mejor manera de calcular el tamaño del programa?
Jack Brounstein
A veces las personas en este sitio copian y pegan su código en mothereff.in/byte-counter . Si se está preguntando acerca de la discrepancia, supongo que Windows está insertando un carácter de nueva línea innecesario al final de su archivo .py (y Windows cuenta una nueva línea como 2 bytes en lugar de 1). De cualquier manera, no tiene que contar esa última línea nueva como parte de su código para fines de puntuación. Si publica una entrada de varias líneas, debe contar 1 para cada carácter de nueva línea, no 2, y no incluir ninguna nueva línea al final de su última línea de código. (Por lo que yo entiendo las reglas de todos modos!)
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)}

Uso:

> 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
plannapus
fuente
Puede eliminar el nombre de la función para guardar 2 bytes.
Alex A.
2

Mathematica, 31 30 bytes

Guardado un byte gracias a Martin Büttner.

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

Uso:

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

Out[1]= {13.4582, 13.4582}
alephalpha
fuente
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)

Usos comando argumentos de la línea de ...asignar a n, ay b, un ingenioso truco que aprendí sobre Lua recientemente.

Cyv
fuente
1

Haskell, 40 bytes

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

Una función anónima. Ejemplo de uso:

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

La función lambda (\(a,b)->((a+b)/2,sqrt$a*b))toma la media aritmética y geométrica en una tupla. Esto se repite comenzando con la primera entrada (una tupla) y luego (!!)indexa la segunda entrada para especificar el número de iteraciones.

xnor
fuente
1

Perl, 60 bytes

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

NB: Según esta meta publicación , creo que tengo la puntuación correcta. El código real (entre comillas simples) es de 58 caracteres, luego agregué +2 para ay pmarcas, ya que esa es la diferencia con la invocación más corta,perl -e'...'

Quejas vagas

Tengo la sensación de que me falta una mejora obvia. Lo sé, "bienvenido al código de golf", pero quiero decir más de lo habitual , creo que hay una oportunidad fácil para acortar esto.

Al principio, había tenido problemas con el uso $\como segundo término con cierto éxito, pero el enfoque anterior terminó siendo 2 bytes más corto, incluso con los apindicadores adicionales necesarios. Del mismo modo, evitar la $_asignación explícita sería bueno, pero el ciclo lo dificulta.

A shift@Fmí también me molesta; Sin embargo, si no lo hago de esa manera (o uso @F=(0,...,...)en su lugar, que no guarda ningún byte), hay un error de uno por uno con la @Fasignación.

Ejemplo

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

Salidas

13.4581714817256 13.4581714817256
type_outcast
fuente
1

Julia, 49 bytes

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

Algoritmo iterativo bastante directo. El uso del símbolo y el retorno múltiple ahorra algunos bytes, pero la sintaxis del bucle for cuesta unos pocos.

Andrew dice reinstalar a Mónica
fuente
1

Haskell, 47 Bytes

f a b 0=(a,b)
f a b n=f((a+b)/2)(sqrt$a*b)(n-1)
gntskn
fuente
podría guardar algunos bytes tomando a ab como pareja en f: fx 0 = x; f (a, b) n = f ((a + b) / 2, sqrt $ a * b) $ n-1
Damien
Y defina la función infijo.
xnor
1

Julia, 42 bytes

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

Esta es una función recursiva fque acepta tres números y devuelve una tupla.

Sin 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
Alex A.
fuente
1

LabVIEW, 21 primitivas de LabVIEW

Las primitivas cuentan según esta meta publicación .

bastante directo, no hay mucho que explicar.

Eumel
fuente
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
wflynny
fuente
3
El programa solo debe imprimir una vez, cuando finaliza.
lirtosiast el
1
Mi malentendido. Fijo.
wflynny
1

CJam, 16 bytes

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

Esta es una función anónima. La entrada es una lista con los dos valores (como dobles), seguida del recuento de iteraciones. Pruébelo en línea con el código de E / S para realizar pruebas.

Normalmente no habría publicado esto porque @PeterTaylor publicó una respuesta CJam igualmente larga antes de ver la pregunta. Pero dado que esto se anuncia como el comienzo de una serie, quería mantener abiertas mis opciones en caso de que la serie sea interesante.

Si bien la longitud es la misma que la respuesta de Peter, el código no lo es. Elegí un formato de entrada diferente al tomar los dos valores en una lista, donde Peter usó valores separados. Entonces, aunque no hay mucho con ninguno de los formatos de entrada, el código se ve bastante diferente.

{     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.
Reto Koradi
fuente
0

Perl 6 ,  53  47 bytes

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

uso:

# 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 cambio la entrada de a,b,na (a,b),npuedo guardar algunos bytes.

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

uso:

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
}

Realmente cambiaría el ... *con ... -> (\a,\b) { a =~= b }, entonces no habría necesidad del $^nparámetro.
(no use en ==lugar de =~=, o puede que no se detenga)

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)
Brad Gilbert b2gills
fuente
0

Prólogo, 80 bytes

Código:

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

Ejemplo:

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

Pruébalo en línea aquí

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

Verifique todos los casos de prueba.

Versión anterior (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;}

Versión anterior (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;}
Monja permeable
fuente