Serie AGM Buco 1: calcola la media aritmetica-geometrica


26

Questa domanda è stata ispirata da questo HNQ .

A proposito della serie

Questa domanda fa ora parte di una serie sul metodo AGM. Questo primo post della serie riguarderà effettivamente il calcolo di AGM. Puoi trattarlo come qualsiasi altra sfida di golf del codice e rispondere senza preoccuparti della serie. Tuttavia, esiste una classifica in tutte le sfide.

Qual è la media aritmetica-geometrica

La media aritmetica-geometrica di due numeri è definita come il numero a cui convergono ripetutamente i mezzi aritmetici e geometrici. Il tuo compito è trovare questo numero dopo alcune niterazioni.

chiarimenti

  • Prendi tre numeri, a, b, nin qualsiasi formato ragionevole.
  • Per niterazioni, prendere la media aritmetica e geometrica di ae bed impostare quelli da ae b.
  • Per due numeri ae b, la media aritmetica è definita come (a + b) / 2.
  • La media geometrica è definita come √(a * b).
  • ae bdovrebbe avvicinarsi a vicenda.
  • Quindi, emettere sia ae b.
  • Non devi preoccuparti di imprecisione galleggiante e simili.
  • Questo è quindi vince il codice più breve in byte !

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

Classifica

Rubato dalla serie di Martin.

Il frammento seguente genererà una classifica in tutte le sfide della serie.

Per assicurarti che le tue risposte vengano visualizzate, inizia ogni risposta con un titolo, utilizzando il seguente modello Markdown:

# Language Name, N bytes

dove N è la dimensione del tuo invio. Se si migliora il punteggio, è possibile mantenere i vecchi punteggi nel titolo, colpendoli. Per esempio:

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


1
I numeri iniziali sono numeri interi positivi?
xnor

2
" entrambi aob " —bene, quale? Entrambi o uno?
Maniglia della porta

@Doorknob -_- Entrambi.
Maltysen,

1
@xnor no. Guarda l'ultimo test-case.
Maltysen,

5
Fare questa parte di una serie provoca una specie di situazione sfortunata. È così semplice che le soluzioni sembreranno tutte abbastanza simili. E pubblicare soluzioni simili in lingue già utilizzate è generalmente disapprovato. Ho scritto la mia soluzione in circa 2 minuti, ma è in una lingua già utilizzata ed è della stessa lunghezza. Se seguo l'etichetta tipica di pubblicazione, non potrò partecipare alla serie.
Reto Koradi,

Risposte:



9

Dyalog APL , 22 21 15 byte

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

Prende ( a , b ) come argomento corretto e richiede n :

(

  +.× punto prodotto di 0,5 e l'argomento giusto

, seguito da

  ×.*⍨"dot power" dell'argomento giusto e 0,5 *

)⍣⎕ tempi applicati al prompt numerico.

* "dot power" è come il prodotto dot, ma utilizza la moltiplicazione e la potenza anziché il plus e la moltiplicazione, come segue:

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

-3 byte grazie a ngn.


Vecchia versione:

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

Prende ncome argomento di sinistra e a bcome argomento di destra.

⊢⍵Sulla RightArg
(... )⍣⍺ricalcola la
(+/÷≢)somma dei tempi di LeftArg divisa per il conteggio
,seguita dalla
.5*⍨×/radice quadrata del prodotto.

Tutti i casi di 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│
└────┴─────┴────────────────┴───────────────────────┴───────────────────────┴───────────────────────┘

È f⍣⍺⊢⍵un linguaggio simile o simile che usi professionalmente?
Lirtosiast

@ThomasKwa Sì, vedi ad esempio Of⍣core⊢TREEsu miserver.dyalog.com (fai clic sulla grande "D" e scorri fino alla riga [266]).
Adám,

7

TI-BASIC, 22 byte

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

Fa esattamente quello che dice l'algoritmo. Prende N dal prompt e A e B attraverso Ansun elenco di due elementi.

Se N è 0, il For(ciclo viene ignorato del tutto.


6

JavaScript ES7, 48 43 byte

-5 grazie a Downgoat!

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

Funzione ricorsiva molto semplice.


2
(a*b)**.5è più corto di Math.sqrt(a*b). esempio
Downgoat

@Downgoat Questo è ES7, ma meh.
Conor O'Brien,

6

MATLAB / Octave, 69 65 byte

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

1
Si potrebbe fare b=(a*b).^5direttamente in quanto non si riutilizzano bnuovamente in quell'iterazione e si salvano 4 byte.
Brain Guider,

6

Gelatina, non competitiva

9 byte Questa risposta non è competitiva, poiché utilizza funzionalità che postdatano la sfida.

SH;P½¥ðṛ¡

Provalo online!

Come funziona

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

Scherzi a parte, 11 byte

,p`;π√@æk`n

Dump esadecimale:

2c70603be3fb40916b606e

Provalo online

Spiegazione:

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

Grazie a @RetoKoradi e @AlexA per avermi salvato 6 byte.

Questo non è competitivo, perché C ++ non è un buon linguaggio per giocare a golf. Fatto questo per divertimento :)

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

Questa è una semplice funzione di ricorsione, molto simile alla risposta JS.


3
Puoi sbarazzarti degli spazi dopo le virgole. Inoltre, l'utilizzo al floatposto di doubleè più breve.
Reto Koradi,

1
Puoi anche rimuovere lo spazio nella #includelinea.
Alex A.

Wow, sono stupido a non accorgermene. Grazie!
TheCoffeeCup

Vorrei considerare f(float*s)che un puntatore a 3 float è in un "formato ragionevole". Non sono sicuro che ciò lo renda più breve.
nwp,

4

K5, 15 byte

Molto letterale:

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

In azione:

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

Sfortunatamente, questo non funziona in oK perché quell'interprete non supporta attualmente la proiezione (curry) di avverbi. Funziona nel vero k5.

In OK, attualmente sarebbe necessario racchiudere la definizione in un lambda:

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

4

J, 18 13 byte

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

Uso:

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

Wow, questo funziona. Le congiunzioni sono strane. Mi aspetterei che questa espressione sia un avverbio (che può essere), ma se presentata con argomenti è anche una funzione.
randomra,

3

Japt , 24 byte 25 33

Salvataggio di 9 7 byte grazie a @ETHproductions

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

Sfrutta la destrutturazione ES6.

Provalo online

Ungolfed && Explanation

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 intervallo di numeri da 0 a U, quindi Uo m@[V,W]=[V+W /2,(V*W q]dovrebbe funzionare. (Non testato)
Produzioni ETH il

Oh, e non dovresti avere assolutamente bisogno delle virgole. :)
ETHproductions

@ETHproductions grazie ancora! :)
Downgoat,

Oh, caro, questo non riesce per nessun Ualtro che 1, producendo ogni ciclo mentre procede. Eccone uno che funziona correttamente:Uo £[VW]=[V+W /2(V*W q]};[VW]
ETHproductions

@ETHproductions grazie, ma l'utilizzo rsembra funzionare anche
Downgoat

3

Matlab, 54 byte

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

Esempio:

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

3

Pyth, 12

u,.OG@*FG2EQ

Test Suite

Spiegazione

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

Dimenticato @e .O, ma non sapevo nemmeno il nuovo scopo di E.
orlp

@orlp ah, non ho visto il tuo post, peccato che avrei solo suggerito questi nei commenti. E sì, tenere traccia di tutte le cose che cambiano è un po 'una lotta: P
FryAmTheEggman

2

Minkolang v0.14, 23 byte

Provalo qui !

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

Grazie a Mathmandan per aver sottolineato una versione più breve utilizzando l' lambdaoperatore.

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

La mia versione originale:

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

Con mio disappunto, una funzione ricorsiva (come la JavaScript e le risposte C ++) era più breve di un semplice ciclo.


2
Puoi accorciarlo un po 'con lambdal' if/elseoperatore ternario :f=lambda a,b,n:f((a+b)/2,(a*b)**.5,n-1)if n else(a,b)
Mathmandan,

Nessun problema! (Inoltre, penso che questo sia 53 byte.)
Mathmandan,

Il file .py che ho salvato è elencato come 55 byte. Esiste un modo migliore per calcolare le dimensioni del programma?
Jack Brounstein,

A volte le persone su questo sito copiano e incollano il loro codice in mothereff.in/byte-counter . Se ti stai chiedendo della discrepanza, immagino che Windows stia inserendo un carattere di nuova riga non necessario alla fine del tuo file .py (e Windows conta una nuova riga come 2 byte anziché 1). In entrambi i casi, non è necessario contare quest'ultima riga come parte del codice ai fini del punteggio. Se pubblichi una voce a più righe, dovresti contare 1 per ogni carattere di nuova riga, non 2 e non includere alcuna nuova riga alla fine dell'ultima riga di codice. (Per quanto io capisca le regole comunque!)
Mathmandan,

2

R, 66 byte

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

È possibile rimuovere il nome della funzione per salvare 2 byte.
Alex A.

2

Mathematica, 31 30 byte

Salvato un byte grazie 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 byte

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

Utilizza argomenti della riga di comando da ...assegnare a n, ae b, un trucco ingegnoso che ho imparato recentemente su Lua.


1

Haskell, 40 byte

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

Una funzione anonima. Esempio di utilizzo:

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

La funzione lambda (\(a,b)->((a+b)/2,sqrt$a*b))prende la media aritmetica e geometrica su una tupla. Viene iterato a partire dal primo input (una tupla), quindi (!!)indicizza il secondo input per specificare il numero di iterazioni.


1

Perl, 60 byte

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

NB: Per questo meta post , credo di avere il punteggio corretto. Il codice effettivo (tra virgolette singole) è di 58 caratteri, quindi ho aggiunto +2 per ae pflag in quanto questa è la differenza dall'invocazione più breve,perl -e'...'

Vaghe lamentele

Ho questa fastidiosa sensazione che mi manchi un evidente miglioramento. Lo so "benvenuto nel codice golf", ma intendo più del solito credo che ci sia una facile opportunità per accorciarlo.

All'inizio, avevo fatto un casino con l'uso $\del secondo termine con un certo successo, ma l'approccio di cui sopra ha finito per essere più corto di 2 byte, anche con le apbandiere extra richieste. Allo stesso modo, evitare l' $_assegnazione esplicita sarebbe bello, ma il ciclo lo rende difficile.

Gli shift@Finsetti anche me; se non lo faccio in questo modo, però (o uso @F=(0,...,...)invece, che non salva alcun byte), c'è un errore off-by-one con l' @Fassegnazione.

Esempio

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

Uscite

13.4581714817256 13.4581714817256

1

Julia, 49 byte

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

Algoritmo iterativo piuttosto diretto. L'uso del simbolo e del ritorno multiplo consente di risparmiare qualche byte, ma la sintassi del ciclo for costa pochi.


1

Haskell, 47 byte

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

potresti salvare alcuni byte prendendo ab come coppia in f: fx 0 = x; f (a, b) n = f ((a + b) / 2, sqrt $ a * b) $ n-1
Damien

E definire la funzione infix.
xnor

1

Julia, 42 byte

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

Questa è una funzione ricorsiva fche accetta tre numeri e restituisce una tupla.

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 Primitives

I primitivi contati secondo questo meta post .

piuttosto semplice, non c'è molto da spiegare.


1

Python 2, 62 61 62 byte

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

3
Il programma dovrebbe stampare una sola volta, quando termina.
Lirtosiast

1
Il mio fraintendimento. Fisso.
wflynny,

1

CJam, 16 byte

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

Questa è una funzione anonima. L'input è un elenco con i due valori (come doppi), seguito dal conteggio dell'iterazione. Provalo online con il codice I / O per il test.

Normalmente non l'avrei pubblicato perché @PeterTaylor ha pubblicato una risposta CJam altrettanto lunga prima di vedere la domanda. Ma poiché questo è pubblicizzato come l'inizio di una serie, volevo mantenere aperte le mie opzioni nel caso in cui la serie fosse interessante.

Mentre la lunghezza è la stessa della risposta di Peter, il codice non lo è. Ho scelto un formato di input diverso prendendo i due valori in un elenco, in cui Peter utilizzava valori separati. Quindi, anche se non c'è molto con entrambi i formati di input, il codice sembra piuttosto diverso.

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

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

utilizzo:

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

Se cambio l'input da a,b,na (a,b),nposso salvare qualche byte.

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

utilizzo:

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
}

Veramente cambierei il ... *con ... -> (\a,\b) { a =~= b }, quindi non ci sarebbe bisogno del $^nparametro.
(non utilizzare al ==posto di =~=o potrebbe non arrestarsi)

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 byte

Codice:

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

Esempio:

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

Provalo online qui


0

Java, 103 96 84 byte

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

Verifica tutti i test.

Vecchia versione (96 byte):

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

Vecchia versione (103 byte):

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;}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.