Seria AGM Otwór 1: Oblicz średnią arytmetyczno-geometryczną

26

To pytanie zostało zainspirowane tym HNQ .

O serii

To pytanie jest teraz częścią serii dotyczącej metody AGM. Ten pierwszy post z serii będzie dotyczył obliczania AGM. Możesz traktować to jak każde inne wyzwanie związane z golfem i odpowiedzieć na nie, nie martwiąc się w ogóle serią. Istnieje jednak tabela wyników dla wszystkich wyzwań.

Co to jest średnia arytmetyczno-geometryczna

Arytmetyczno-średnia geometryczna z dwóch liczb jest definiowana jako liczba że wielokrotnie biorąc Środkach arytmetyczne i geometryczne zbiegają się. Twoim zadaniem jest znalezienie tego numeru po kilku niteracjach.

Wyjaśnienia

  • Bierzesz trzy liczby, a, b, nw dowolnym rozsądnym formacie.
  • Dla niteracji, wziąć średnią arytmetyczną i średnią geometryczną ai bi ustaw tych, aa b.
  • Dla dwóch liczb ai bśrednią arytmetyczną definiuje się jako (a + b) / 2.
  • Średnia geometryczna jest zdefiniowana jako √(a * b).
  • ai bpowinni się do siebie zbliżać.
  • Następnie wypisz zarówno ai b.
  • Nie musisz się martwić niedokładnością pływaka i tym podobne.
  • To jest więc wygrywa najkrótszy kod w bajtach !

Przypadki testowe

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

Tabela liderów

Skradziony z serii Martina.

Poniższy fragment wygeneruje tabelę wyników we wszystkich wyzwaniach serii.

Aby mieć pewność, że Twoje odpowiedzi się pojawią, zacznij każdą odpowiedź od nagłówka, używając następującego szablonu Markdown:

# Language Name, N bytes

gdzie N jest rozmiarem twojego zgłoszenia. Jeśli poprawisz swój wynik, możesz zachować stare wyniki w nagłówku, przekreślając je. Na przykład:

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

Maltysen
źródło
1
Czy początkowe liczby są dodatnimi liczbami całkowitymi?
xnor
2
jedno alub drugieb ” - cóż, które? Oba, czy jedno?
Klamka
@Doorknob -_- Jego oba.
Maltysen
1
@xnor no. Spójrz na ostatni przypadek testowy.
Maltysen
5
Włączenie tej części serii powoduje coś niefortunnego. Jest to tak proste, że wszystkie rozwiązania będą wyglądały dość podobnie. A publikowanie podobnych rozwiązań w językach, które były już używane, jest ogólnie mile widziane. Napisałem swoje rozwiązanie w około 2 minuty, ale jest w języku, który był już używany i ma tę samą długość. Jeśli będę przestrzegać typowej etykiety zamieszczania postów, nie będę mógł uczestniczyć w serii.
Reto Koradi,

Odpowiedzi:

10

CJam, 16 bajtów

{{_2$+2/@@*mq}*}

Pobiera dane wejściowe na stosie jako a b nmiejsce ai bsą podwajane. Demo online

Peter Taylor
źródło
9

Dyalog APL , 22 21 15 bajtów

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

Bierze ( a , b ) jako właściwy argument i monituje o n :

(

  +.× iloczyn skalarny 0,5 i odpowiedni argument

, śledzony przez

  ×.*⍨„moc kropki” odpowiedniego argumentu i 0,5 *

)⍣⎕ zastosowane czasy numeryczne.

* „Moc kropkowa” jest jak iloczyn skalarny, ale z wykorzystaniem mnożenia i mocy zamiast plus i mnożenia, jak następuje:

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

-3 bajty dzięki ngn.


Stara wersja:

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

Przyjmuje njako lewy argument i a bprawy argument.

⊢⍵Na RightArg
(... )⍣⍺ponownie oblicz
(+/÷≢)sumę razy LeftArg podzieloną przez sumę,
,po której następuje
.5*⍨×/pierwiastek kwadratowy produktu.

Wszystkie przypadki testowe:

      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ám
źródło
Czy jest f⍣⍺⊢⍵to idiom, którego używasz profesjonalnie?
lirtosiast
@ThomasKwa Tak, patrz np. Of⍣core⊢TREENa miserver.dyalog.com (kliknij dużą literę „D” i przewiń do wiersza [266]).
Adám
7

TI-BASIC, 22 bajty

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

Robi dokładnie to, co mówi algorytm. Pobiera N z monitu, a A i B Ansjako listę dwuelementową.

Jeśli N wynosi 0, For(pętla jest całkowicie pomijana.

lirtosiast
źródło
6

JavaScript ES7, 48 43 bajtów

-5 dzięki Downgoat!

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

Bardzo prosta funkcja rekurencyjna.

Conor O'Brien
źródło
2
(a*b)**.5jest krótszy niż Math.sqrt(a*b). przykład
Downgoat
@Downgoat To ES7, ale meh.
Conor O'Brien,
6

MATLAB / Octave, 69 65 bajtów

function [a,b]=r(a,b,n)
for i=1:n;j=(a+b)/2;b=(a*b)^.5;a=j;end
costrom
źródło
1
Możesz to zrobić b=(a*b).^5bezpośrednio, ponieważ nie będziesz bponownie używać tej iteracji i zaoszczędzisz 4 bajty.
Brain Guider,
6

Galaretka, niekonkurująca

9 bajtów Ta odpowiedź nie jest konkurencyjna, ponieważ korzysta z funkcji, które datują wyzwanie.

SH;P½¥ðṛ¡

Wypróbuj online!

Jak to działa

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
źródło
5

Poważnie, 11 bajtów

,p`;π√@æk`n

Hex Dump:

2c70603be3fb40916b606e

Wypróbuj online

Wyjaśnienie:

,                    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.
kwintopia
źródło
5

C ++, 108 102 100 bajtów

Dziękuję @RetoKoradi i @AlexA za uratowanie mi 6 bajtów.

Jest to niekonkurencyjne, ponieważ C ++ nie jest dobrym językiem golfowym. Zrobiłem to dla zabawy :)

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

Jest to prosta funkcja rekurencyjna, bardzo podobna do odpowiedzi JS.

TheCoffeeCup
źródło
3
Możesz pozbyć się spacji po przecinkach. Używanie floatzamiast zamiast doublejest krótsze.
Reto Koradi,
1
Możesz także usunąć spację w #includelinii.
Alex A.,
Wow, jestem głupia, żeby tego nie zauważyć. Dzięki!
TheCoffeeCup
Zastanowiłbym się, f(float*s)który wskaźnik do 3 liczb zmiennoprzecinkowych ma być w „rozsądnym formacie”. Nie jestem pewien, czy to faktycznie skraca to.
nwp
4

K5, 15 bajtów

Bardzo dosłownie:

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

W akcji:

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

Niestety nie działa to w OK, ponieważ ten tłumacz nie obsługuje obecnie projekcji (curry) przysłówków. Działa w prawdziwym k5.

W ok obecnie byłoby konieczne zawinięcie definicji w lambda:

  {x{(+/x%2;%*/x)}/y}[5; 24 6]
13.4582 13.4582
JohnE
źródło
4

J, 18 13 bajtów

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

Stosowanie:

   agm =: -:@+/,%:@*/^:
   5 agm 24 6
13.4582 13.4582
alephalpha
źródło
Wow, to działa. Koniunkcje są dziwne. Spodziewałbym się, że to wyrażenie będzie przysłówkiem (którym może być), ale jeśli zostanie przedstawione z argumentami, będzie również funkcją.
randomra
3

Japt , 24 bajty 25 33

Zaoszczędź 9 7 bajtów dzięki @ETHproductions

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

Korzysta z destrukcji ES6.

Wypróbuj online

Niegolfowane i objaśnienia

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
źródło
Uogeneruje zakres liczb od 0 do U, więc Uo m@[V,W]=[V+W /2,(V*W q]powinno działać. (Nie
przetestowano
Aha, i nie powinieneś wcale potrzebować przecinków. :)
ETHproductions
@ETHproductions jeszcze raz dziękuję! :)
Downgoat
Och, kochanie, to nie powiedzie się dla żadnego Uinnego niż 1, wysyłając każdą pętlę w miarę jej działania. Oto jeden, który działa poprawnie:Uo £[VW]=[V+W /2(V*W q]};[VW]
ETHprodukcje
Dzięki @ETHproductions, ale używanie rwydawało się również działać
Downgoat
3

Matlab, 54 bajty

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

Przykład:

>> f([24 6], 2)
ans =
  13.500000000000000  13.416407864998739
Luis Mendo
źródło
3

Pyth, 12

u,.OG@*FG2EQ

Pakiet testowy

Wyjaśnienie

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
źródło
Zapomniałem @i .O, ale nawet nie znałem nowego celu E.
lub
@orlp ah, nie widziałem twojego postu, mój zły, po prostu zasugerowałem to w komentarzach. I tak, śledzenie wszystkich zmieniających się rzeczy jest trochę
trudne
2

Minkolang v0.14, 23 bajty

Wypróbuj tutaj !

$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
źródło
2

Pyth, 15 bajtów

u,^*FG.5csG2vzQ
orlp
źródło
2

Python 3, 65 55 bajtów

Dzięki Mathmandan za wskazanie krótszej wersji za pomocą lambdaoperatora.

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

Moja oryginalna wersja:

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

Ku mojemu rozczarowaniu funkcja rekurencyjna (a mianowicie odpowiedzi na JavaScript i C ++) była krótsza niż prosta pętla for.

Jack Brounstein
źródło
2
Możesz to trochę skrócić za pomocą lambdai if/elseoperatora trójskładnikowego :f=lambda a,b,n:f((a+b)/2,(a*b)**.5,n-1)if n else(a,b)
mathmandan
Nie ma problemu! (
Wydaje
Zapisany przeze mnie plik .py ma 55 bajtów. Czy istnieje lepszy sposób na obliczenie rozmiaru programu?
Jack Brounstein,
Czasami ludzie na tej stronie kopiują i wklejają swój kod do mothereff.in/byte-counter . Jeśli zastanawiasz się nad rozbieżnością, domyślam się, że Windows wstawia niepotrzebny znak nowej linii na końcu pliku .py (a Windows liczy nową linię jako 2 bajty zamiast 1). Tak czy inaczej, nie musisz liczyć ostatniej linii nowego wiersza jako części kodu do celów punktacji. Jeśli opublikujesz wpis składający się z wielu wierszy, powinieneś policzyć 1 dla każdego znaku nowej linii, a nie 2 i nie włączając żadnej nowej linii na końcu ostatniego wiersza kodu. (O ile i tak rozumiem zasady!)
matematyka
2

R, 66 bajtów

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

Stosowanie:

> 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
źródło
Możesz usunąć nazwę funkcji, aby zapisać 2 bajty.
Alex A.,
2

Mathematica, 31 30 bajtów

Oszczędność jednego bajtu dzięki Martinowi Büttnerowi.

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

Stosowanie:

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

Out[1]= {13.4582, 13.4582}
alephalpha
źródło
1

Lua, 62 bajty

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

Zastosowania polecenia argumenty wiersza z ...przypisać do n, ai b, fajną sztuczkę dowiedziałem się o Lua niedawno.

Cyv
źródło
1

Haskell, 40 bajtów

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

Anonimowa funkcja. Przykładowe użycie:

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

Funkcja lambda (\(a,b)->((a+b)/2,sqrt$a*b))przyjmuje krotkę średnią arytmetyczną i geometryczną. Jest to iterowane począwszy od pierwszego wejścia (krotki), a następnie (!!)indeksuje drugie wejście, aby określić liczbę iteracji.

xnor
źródło
1

Perl, 60 bajtów

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

NB: Według tego meta postu uważam , że mam poprawną punktację. Rzeczywisty kod (między pojedynczymi cudzysłowami) składa się z 58 znaków, a następnie dodałem +2 dla ai pflagi, ponieważ jest to różnica od najkrótszego wywołania,perl -e'...'

Niejasne skargi

Mam dokuczliwe wrażenie, że brakuje mi oczywistej poprawy. Wiem, „witaj w golfa kodowania”, ale mam na myśli więcej niż zwykle. Sądzę, że istnieje łatwa okazja, aby to skrócić.

Na początku miałem problemy z używaniem $\jako drugiego terminu z pewnym sukcesem, ale powyższe podejście skończyło się o 2 bajty krótsze, nawet z apwymaganymi dodatkowymi flagami. Podobnie unikanie wyraźnego $_przypisania byłoby fajne, ale pętla utrudnia to.

Te shift@Fbłędy ja też; jeśli jednak nie zrobię tego w ten sposób (lub użyję @F=(0,...,...)zamiast tego, co nie zapisuje żadnych bajtów), przy @Fprzypisaniu występuje błąd „jeden po drugim” .

Przykład

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

Wyjścia

13.4581714817256 13.4581714817256
type_outcast
źródło
1

Julia, 49 bajtów

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

Całkiem bezpośredni algorytm iteracyjny. Użycie symbolu i wielokrotnego powrotu pozwala zaoszczędzić kilka bajtów, ale składnia pętli for kosztuje kilka.

Andrew mówi Przywróć Monikę
źródło
1

Haskell, 47 bajtów

f a b 0=(a,b)
f a b n=f((a+b)/2)(sqrt$a*b)(n-1)
gntskn
źródło
możesz zapisać niektóre bajty biorąc ab jako parę w f: fx 0 = x; f (a, b) n = f ((a + b) / 2, sqrt $ a * b) $ n-1
Damien
I zdefiniuj infix funkcji.
xnor
1

Julia, 42 bajty

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

Jest to funkcja rekurencyjna, fktóra przyjmuje trzy liczby i zwraca krotkę.

Nie golfowany:

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.
źródło
1

LabVIEW, 21 Prymitywów LabVIEW

Prymitywy liczone zgodnie z tym postem .

całkiem nieźle do przodu, niewiele do wyjaśnienia.

Eumel
źródło
1

Python 2, 62 61 62 bajtów

def f(a,b,n):
 while n:a,b=(a+b)/2.,(a*b)**.5;n-=1
 print a,b
wflynny
źródło
3
Program powinien wydrukować tylko raz, gdy zakończy działanie.
lirtosiast
1
Moje nieporozumienie. Naprawiony.
wflynny
1

CJam, 16 bajtów

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

To anonimowa funkcja. Dane wejściowe to lista z dwiema wartościami (jako liczba podwójna), po której następuje liczba iteracji. Wypróbuj online z kodem I / O do testowania.

Normalnie nie napisałbym tego, ponieważ @PeterTaylor opublikował równie długą odpowiedź CJam, zanim zobaczyłem pytanie. Ale ponieważ jest to reklamowane jako początek serii, chciałem zachować moje opcje otwarte, na wypadek gdyby seria była interesująca.

Chociaż długość jest taka sama jak odpowiedź Piotra, kod nie jest. Wybrałem inny format wejściowy, biorąc dwie wartości z listy, gdzie Peter użył osobnych wartości. Więc chociaż w obu formatach wejściowych jest niewiele, kod wygląda zupełnie inaczej.

{     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
źródło
0

Perl 6 ,  53  47 bajtów

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

stosowanie:

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

Jeśli zmienię wejście z a,b,nna (a,b),n, mogę zapisać kilka bajtów.

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

stosowanie:

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
}

Naprawdę chciałbym zamienić się z ... *ze ... -> (\a,\b) { a =~= b }, wtedy nie byłoby potrzeby dla $^nparametru.
(nie używaj ==zamiast =~=, bo może się nie zatrzymać)

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
źródło
0

Prolog, 80 bajtów

Kod:

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

Przykład:

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

Wypróbuj online tutaj

Emigna
źródło
0

Java, 103 96 84 bajtów

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

Sprawdź wszystkie przypadki testowe.

Stara wersja (96 bajtów):

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

Stara wersja (103 bajty):

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;}
Leaky Nun
źródło