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


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

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


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.


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

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.

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.

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.


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

4

J, 18 13 bytes

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

Uso:

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

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]

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

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

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


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.


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

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}

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.


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.


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

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.


1

Haskell, 47 Bytes

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

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


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

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)

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í


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;}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.