zrzeczenie się odpowiedzialności: Średnia wartość jest tworzona przeze mnie
Zdefiniuj średnią arytmetyczną liczb jako
Zdefiniuj średnią geometryczną liczb jako
Zdefiniuj średnią harmoniczną liczb jako
Zdefiniuj średnią kwadratową liczby jako
Średnia średnia ( ) jest zdefiniowana następująco: Zdefiniuj cztery sekwencje ( ) jakonM.1( x1, . . . , xn) = x1+ x2)+ . . . + xnn
nM.0( x1, . . . , xn) = x1x2). . . xn--------√n
nM.- 1( x1, . . . , xn) = n1x2)+ 1x2)+ . . . + 1xn
nM.2)( x1, . . . , xn) = x2)1+ x2)2)+ . . . + x2)nn--------------√
M.M.k,bk,ck,dka0=M1(x1,...,xn),zak, bk, ck, dkza0= M.1( x1, . . . , xn) ,b0= M.0( x1, . . . , xn) ,do0= M.- 1( x1, . . . , xn) ,re0= M.2)( x1, . . . , xn) ,zak + 1= M.1( ak, bk, ck, dk) ,bk + 1= M.0( ak, bk, ck, dk) ,dok + 1= M.- 1( ak, bk, ck, dk) ,rek + 1= M.2)( ak, bk, ck, dk)
Wszystkie cztery sekwencje są zbieżne do ten sam numer, .M.M.( x1, x2), . . . , xn)
Przykład
Średnia wartość 1 i 2 jest obliczana w następujący sposób: zacznij od
Następnie
Dalsze obliczanie sekwencji powinno być jasne. Można zauważyć, że zbiegają się one do tej samej liczby, około .za0= ( 1 + 2 ) / 2 = 1,5 , b0= 1 ∗ 2----√= 2-√≈ 1,4142 ,do0= 211+ 12)= 43)≈ 1,3333 , d0= 12)+ 22)2)-------√= 52)--√≈ 1,5811.
1=1,5+1,4142+1,3333+1,5811za1= 1,5 + 1,4142 + 1,3333 + 1,58114≈ 1,4571 ,b1= 1,5 ∗ 1,4142 ∗ 1,3333 ∗ 1,5811-----------------------√4≈ 1,4542 ,do1= 411.5+ 11,4142+ 11,3333+ 11,5811≈ 1,4512 ,re1= 1,52)+ 1,41422)+ 1,33332)+ 1,58112)4----------------------------√≈ 1,4601.
1,45568889
Wyzwanie
Biorąc pod uwagę dwie dodatnie liczby rzeczywiste, i ( ), obliczyć ich średnią średnicę .zaba < bM.M.( a , b )
Przypadki testowe
1 1 => 1
1 2 => 1.45568889
100 200 => 145.568889
2.71 3.14 => 2.92103713
0.57 1.78 => 1.0848205
1.61 2.41 => 1.98965438
0.01 100 => 6.7483058
Notatki
- Twój program jest ważny, jeśli różnica między jego wyjściem a poprawnym wyjściem nie jest większa niż 1/100000 wartości bezwzględnej różnicy między liczbami wejściowymi.
- Wynik powinien być pojedynczą liczbą.
To jest golf golfowy , więc wygrywa najkrótszy kod!
Odpowiedzi:
Wolfram Język (Mathematica) , 52 bajtów
Wypróbuj online!
W pierwszym podejściu użyłem tych wbudowanych
Mean
GeometricMean
HarmonicMean
iRootMeanSquare
Oto niektóre podstawienia dla zapisywania bajtów
HarmonicMean
->1/Mean[1/x]
autor: @Robin Ryder (zapisane 3 bajty)GeometricMean
->E^Mean@Log@x
autor: @A. Rex (2 bajty zapisane)RootMeanSquare
->Mean[x^2]^.5
według @A. Rex (zapisane 4 bajty)wreszcie możemy przypisać
Mean
doM
(zgodnie z propozycją @ovs) i zaoszczędzić 5 dodatkowych bajtówźródło
#//.x_:>N@{Mean@x,E^Mean@Log@x,1/Mean[1/x],Mean[x^2]^.5}&
R,
706967 bajtówWypróbuj online!
-1 bajt z lepszą kondycją.
-2 bajty, przechodząc do bazy 2.
Podobnie jak niektóre inne odpowiedzi, używa wyrażenia średniej geometrycznej jako średniej arytmetycznej na skali logarytmicznej (tutaj w bazie 2):M0(x1,…,xn)=2M1(log2x1,…,log2xn).
Wykorzystuje również fakt, że , tj. . Warunek jest zatem równoważny , którego używam w pętli while; osiąga się to poprzez nadużywanie składni, której pierwszy element bierze pod uwagę tylko warunek, który jest wektorem, a zatem kolejność, w jakiej są przechowywane środki. (Zauważ, że moglibyśmy również użyć ponieważ jest to minimum cztery, ale nie mogliśmy użyć lub pod warunkiem.)∀k,dk≥ak≥bk≥ck dk=max(ak,bk,ck,dk) ak=bk=ck=dk dk=M1(ak,bk,ck,dk) ck ak bk
while
Kiedy wychodzimy z pętli while,
x
jest wektorem stałym. Finał?x
oblicza swój sposób sprowadzenia go do skalara.źródło
J , 34 bajty
(31 jako wyrażenie bez przypisania do zmiennej
f
)Wypróbuj online!
Dla funkcji
a
ib
,a &.: b
( „a pod b” ( związane wyzwanie )) jest równoważne(b inv) a b
- zastosowanie b, a następnie, po czym odwrotnością b. W tym przypadku średnia geometryczna / harmoniczna / kwadratowa jest odpowiednio średnią arytmetyczną „pod” logarytmem, inwersją i kwadratem.źródło
TI-BASIC,
423534 bajtów-1 bajt dzięki @SolomonUcko
Dane wejściowe to lista dwóch liczb całkowitych w
Ans
.Dane wyjściowe są zapisywane
Ans
i automatycznie drukowane po zakończeniu programu.Formuły stosowane do średnich geometrycznych, harmonicznych i kwadratowych są oparte na wyjaśnieniach użytkownika202729 .
Przykład:
Objaśnienie:
(Newlines zostały dodane w celu wyjaśnienia. NIE pojawiają się w kodzie).
Uwagi:
TI-BASIC jest językiem tokenizowanym. Liczba znaków nie jest równa liczbie bajtów.
e^(
to ten jednobajtowy token.^-1
jest używany dla tego jednobajtowego tokena. Zamiast tegozdecydowałem się na pisanie,
^-1
ponieważ token wygląda jakֿ¹
w bloku kodu.√(
to ten jednobajtowy token.ΔList(
to ten dwubajtowy token.źródło
max(DeltaList(Ans
->variance(Ans
.Java 10,
234229214211215206203196180177 bajtów-5 bajtów dzięki @PeterCordes .
-15 dodatkowych bajtów dzięki @PeterCordes , zainspirowanej odpowiedzią R @RobinRyder .
+4 bajty, ponieważ zakładałem, że dane wejściowe są zamówione w przedsprzedaży.
-27 bajtów dzięki @ OlivierGrégoire .
Wypróbuj online.
Wyjaśnienie:
źródło
f+=Math.abs(d-D)<1e-9;
uzyskać domyślną konwersję z wyniku porównania wartości logicznej na liczbę całkowitą 0/1, a następniedouble
. Czy Java ma do tego kompaktową składnię? Czy też można to zrobić,f+=Math.abs(d-D)
a następnie sprawdzić, czy suma różnic bezwzględnych jest wystarczająco mała ?f>1e-8
działa jako warunek pętli: 229 bajtów.a->{for(double f=1,D,A[],l;f>1e-8;a=A){D=a[0];A=new double[]{f=0,1,0,0};for(var d:a){f+=Math.abs(d-D);A[0]+=d;A[1]*=d;A[2]+=1/d;A[3]+=d*d;}A[0]/=l=a.length;A[1]=Math.pow(A[1],1/l);A[2]=l/A[2];A[3]=Math.sqrt(A[3]/l);}return a[0];}
. Dzięki1e-9
działa wolniej (około dwa razy szybciej niż procesor), co oznacza konieczność wykonania większej liczby iteracji, aby uzyskać w zasadzie 4 * niższą wartośćd-D
. Dzięki1e-7
jest mniej więcej taka sama jak prędkość 1e-8. Z1e-6
, niektóre cyfry końcowe różnią się dla jednego przypadku.f
całkowicie i tylko sprawdzića[3]-a[2]<4e-9
.l==2||
masz na myśli ( grał w golfal<3|
). Ale tak, dobra uwaga; Dodałem to. :)Węgiel drzewny , 40 bajtów
Wypróbuj online! Link jest do pełnej wersji kodu. Pobiera dane wejściowe jako tablicę liczb. Wyjaśnienie:
Powtarzaj, gdy tablica zawiera różne wartości ...
... zamień tablicę na listę wartości:
... znaczy ...
... środek geometryczny ...
... średnia harmoniczna ...
... i pierwiastek średni kwadrat.
Rzuć element tablicy na ciąg i niejawnie go wydrukuj.
źródło
Galaretka , 24 bajty
Wypróbuj online!
źródło
PowerShell ,
182180183 bajtówWypróbuj online!
źródło
05AB1E ,
262423 bajtówWypróbuj online lub zobacz kroki wszystkich przypadków testowych .
-1 bajt dzięki @Grimy .
23 bajtowa alternatywa dla średniej geometrycznej:
Wypróbuj online lub zobacz kroki wszystkich przypadków testowych .
Wyjaśnienie:
źródło
Δ©P®gzm®ÅA®zÅAz®nÅAt)}н
Y
2/4. :)Δ©ÅA®.²ÅAo®zÅAz®nÅAt)}н
. Niestety nie wygląda na to, żebyśmy mogli refaktoryzować wszystkie teÅA
.Galaretka ,
2524 bajtówWypróbuj online!
Wyjaśnienie
źródło
P*İL
pracy dla środka geometrycznego?P*Lİ$
żeby nie oszczędzać bajtów. Oznaczałoby to, że mogę obniżyćÆm
linię bez kosztowania bajtów, ale podoba mi się fakt, że każdy z nich ma obecnie średnią arytmetyczną.Python 3 , 152 bajty
Wypróbuj online!
Funkcja rekurencyjna
f
zbiegnie się do precyzji zmiennoprzecinkowej. Działa w zasadzie dla wszystkich list liczb dodatnich o dowolnym rozmiarze, ale jest ograniczony ograniczeniemrekurencji Pythonadla niektórych przypadków testowych.Alternatywnie, z dokładnością do 9 miejsc po przecinku:
Python 3 , 169 bajtów
Wypróbuj online!
źródło
C # , 173 bajtów
Wypróbuj online!
źródło
using System
iusing System.Linq
w liczbie bajtów, ponieważ są one wymagane dla programu do uruchomienia. Możesz zmienić swój kompilator na C # Visual Interactive Compiler, który nie potrzebuje tych importów. Ponadto,1.0
->1d
Czysty , 124 bajty
Wypróbuj online!
Wykonuje operację, aż wynik przestanie się zmieniać.
Hurra, aby uzyskać zmiennoprzecinkową ograniczoną precyzję!
źródło
Pyth, 32 bajty
Spróbuj go online tutaj , lub sprawdzić wszystkie przypadki testowe (bar dwa, patrz uwaga poniżej) od razu tutaj . Akceptuje dane wejściowe jako listę.
Wydaje się, że występują pewne problemy z zaokrąglaniem, ponieważ niektóre dane wejściowe nie są zbieżne poprawnie, gdy powinny. W szczególności przypadek testowy
0.01 100
blokuje się przy wartościach[6.748305820749738, 6.748305820749738, 6.748305820749739, 6.748305820749738]
, a przypadek testowy1.61 2.41
blokuje się przy wartościach[1.9896543776640825, 1.9896543776640825, 1.9896543776640827, 1.9896543776640825]
- zauważ w obu przypadkach, że trzecia średnia (średnia harmoniczna) różni się od pozostałych.Nie jestem pewien, czy ten problem unieważnia mój wpis, ale i tak go publikuję, ponieważ powinien działać. Jeśli nie jest to do przyjęcia, można to naprawić, wprowadzając
.RRT
przed[
, zaokrąglanie każdego ze średnich do 10 miejsc po przecinku, jak widać w tym zestawie testów .źródło
.Wt{H
zu
do -4 bajtów (i zmianyZ
doG
)Japt v2.0a0
-g
,4238 bajtówMusi być krótsza droga ... To jest potworność! Zaoszczędź 4 bajty dzięki @Shaggy!
Spróbuj
źródło
C # (interaktywny kompilator Visual C #) , 177 bajtów
Dzięki @KevinCruijjsen za zwrócenie uwagi, że stosowanie precyzji zmiennoprzecinkowej powoduje problemy! Wyniosłoby 163 bajty, gdyby podwójne były idealnie precyzyjne.
Wypróbuj online!
źródło
StackOverflowException
precyzję zmiennoprzecinkową. Zamiastc==g[0]
ciebie możesz zrobić coś takiegoMath.Abs(c-g[0])<1e-9
. Wypróbuj online.Kod maszynowy x86 (liczba zmiennoprzecinkowa SIMD przy użyciu 128-bitowego SSE1 i AVX) 94 bajty
Kod maszynowy x86 (SIMD 4x dwukrotnie przy 256-bitowym AVX) 123 bajty
float
przechodzi pytania testowe w pytaniu, ale z progiem wyjścia pętli wystarczająco małym, aby tak się stało, łatwo utknie w nieskończonej pętli z losowymi danymi wejściowymi.Instrukcje upakowanej pojedynczej precyzji SSE1 mają 3 bajty, ale SSE2 i proste instrukcje AVX mają 4 bajty. (Instrukcje takie jak pojedyncze skalarne
sqrtss
mają także 4 bajty długości, dlatego używam ich,sqrtps
chociaż zależy mi tylko na niskim elemencie. Nie jest nawet wolniejszy niż sqrts na nowoczesnym sprzęcie). Użyłem AVX do nieniszczącego miejsca docelowego, aby zapisać 2 bajty vs. movaps + op.W wersji podwójnej możemy jeszcze zrobić kilka,
movlhps
aby skopiować 64-bitowe fragmenty (ponieważ często dbamy tylko o niski element sumy poziomej). Pozioma suma 256-bitowego wektora SIMD również wymaga dodatkowej wartości,vextractf128
aby uzyskać wysoką połowę, w porównaniu do powolnej, ale małej 2xhaddps
strategii float . Thedouble
wersja wymaga także 2x 8-bajtowych stałych zamiast 2x 4-bajtowych. Ogólnie rzecz biorąc, okazuje się, że jest blisko 4/3 wielkościfloat
wersji.mean(a,b) = mean(a,a,b,b)
dla wszystkich 4 tych środków , więc możemy po prostu powielić dane wejściowe do 4 elementów i nigdy nie musimy implementować długości = 2. W ten sposób możemy na przykład zakodować średnią geometryczną jako 4. root = sqrt (sqrt). I potrzebujemy tylko jednej stałej FP4.0
.Mamy jeden wektor SIMD ze wszystkich 4
[a_i, b_i, c_i, d_i]
. Na tej podstawie obliczamy 4 średnie jako skalary w osobnych rejestrach i tasujemy je z powrotem do następnej iteracji. (Operacje poziome na wektorach SIMD są niewygodne, ale musimy zrobić to samo dla wszystkich 4 elementów w wystarczającej liczbie przypadków, aby się wyrównały. Zacząłem od wersji x87, ale robiło się to bardzo długo i nie było fajnie.)Warunek pętli wyjście
}while(quadratic - harmonic > 4e-5)
(lub mniejsza stała dladouble
) opiera się na @ RobinRyder badawczo odpowiedzi i odpowiedź Java Kevin Cruijssen za : średniej kwadratowej jest zawsze największa wielkość, a średnia harmoniczna jest zawsze najmniejsze (ignorując błędy zaokrąglenia). Możemy więc sprawdzić różnicę między tymi dwoma, aby wykryć zbieżność. Zwracamy średnią arytmetyczną jako wynik skalarny. Zwykle jest pomiędzy tymi dwoma i jest prawdopodobnie najmniej podatna na błędy zaokrąglania.Wersja pływająca : wywoływalna jak
float meanmean_float_avx(__m128);
z arg i zwracana wartość w xmm0. (Więc x86-64 System V lub Windows x64, ale nie szybka x64.) Lub zadeklaruj typ zwracany__m128
, abyś mógł uzyskać kwadratową i harmoniczną średnią dla testu.Pozwolenie temu wziąć 2 oddzielne
float
argumenty w xmm0 i xmm1 kosztowałoby 1 dodatkowy bajt: potrzebowalibyśmyshufps
znaku imm8 (zamiast po prostuunpcklps xmm0,xmm0
), aby przetasować razem i zduplikować 2 dane wejściowe.(Lista NASM utworzona za pomocą
nasm -felf64 mean-mean.asm -l/dev/stdout | cut -b -34,$((34+6))-
. Usuń część listy i odzyskaj źródło za pomocącut -b 34- > mean-mean.asm
)Suma pozioma SIMD i dzielenie przez 4 (tj. Średnia arytmetyczna) jest zaimplementowana w osobnej funkcji, którą my
call
(ze wskaźnikiem funkcji amortyzującym koszt adresu). Z4/x
przed / po, lubx^2
przed i sqrt po, otrzymujemy średnią harmoniczną i kwadratową. (Bolesne było pisanie tychdiv
instrukcji zamiast mnożenia przez dokładnie reprezentowalne0.25
).Średnia geometryczna jest implementowana osobno z pomnożonym i połączonym sqrt. Lub najpierw z jednym sqrt, aby zmniejszyć wielkość wykładnika i może pomóc w precyzji numerycznej. log nie jest dostępny, tylko
floor(log2(x))
przez AVX512vgetexpps/pd
. Exp jest w pewnym sensie dostępny przez AVX512ER (tylko Xeon Phi), ale z precyzją 2 ^ -23.Mieszanie 128-bitowych instrukcji AVX i starszych SSE nie stanowi problemu z wydajnością. Mieszanie 256-bitowego AVX ze starszym SSE może odbywać się na Haswell, ale na Skylake potencjalnie tworzy potencjalną fałszywą zależność dla instrukcji SSE. Wydaje mi się, że moja
double
wersja pozwala uniknąć niepotrzebnych łańcuchów deponowanych w pętli i wąskich gardeł w zakresie opóźnień / przepustowości div / sqrt.Wersja podwójna:
Uprząż testowa C.
Kompiluj za pomocą:
Oczywiście potrzebujesz procesora z obsługą AVX lub emulatora takiego jak Intel SDE. Aby skompilować na hoście bez macierzystej obsługi AVX, użyj
-march=sandybridge
lub-mavx
Uruchom: przekazuje zakodowane na stałe przypadki testowe, ale w przypadku wersji zmiennoprzecinkowej przypadkowe przypadki testowe często nie spełniają
(b-a)/10000
wartości progowej określonej w pytaniu.Błędy FP są wystarczające, aby poczwórne uszkodzenie wyszło mniej niż zero dla niektórych danych wejściowych.
Lub bez
a += 1<<11; b += (1<<12)+1;
komentarza:Żaden z tych problemów nie występuje
double
. Skomentujprintf
przed każdym testem, aby zobaczyć, że wyjście jest puste (nic zif(delta too high)
bloku).DO ZROBIENIA: użyj
double
wersji jako odniesienia dofloat
wersji, zamiast tylko patrzeć, jak zbiegają się z poczwórnym uszkodzeniem.źródło
JavaScript - 186 bajtów
Pobiera dane wejściowe jako tablicę liczb. Wykorzystuje średnie transformacje w odpowiedzi J42161217, aby skrócić kod.
Wypróbuj online
Wyjaśnienie
źródło
Perl 5 ,
9272 bajtyWypróbuj online!
... używając brudnych sztuczek.
źródło
SNOBOL4 (CSNOBOL4) , 296 bajtów
Wypróbuj online!
Prosta implementacja. Używa triku z mojej odpowiedzi na powiązane pytanie do golfa.
źródło