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


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:



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

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.



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

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.

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.

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.


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

4

J, 18 13 bajtów

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

Stosowanie:

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

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]

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

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

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


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.


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

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}

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.


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.


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

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.


1

Haskell, 47 bajtów

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

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

1

LabVIEW, 21 Prymitywów LabVIEW

Prymitywy liczone zgodnie z tym postem .

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


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

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.

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)

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


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;}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.