disclaimer: Mean berarti dibuat oleh saya
Tentukan mean aritmetik dari n angka sebagai
M1(x1,...,xn)=x1+x2+...+xnn
Tentukan mean geometrik darinangka sebagai
M0(x1,...,xn)=x1x2...xn−−−−−−−−√n
Tentukan rata-rata harmonik dariangka sebagai
Tentukan rata-rata kuadratik dariangkasebagai
Mean Mean () didefinisikan sebagai berikut: Tentukan empat urutan (nM−1(x1,...,xn)=n1x2+1x2+...+1xn
nM2(x1,...,xn)=x21+x22+...+x2nn−−−−−−−−−−−−−−√
MMak,bk,ck,dk ) sebagaiSebuah0= M1( x1, . . . , xn) ,b0= M0( x1, . . . , xn) ,c0= M- 1( x1, . . . , xn) ,d0= M2( x1, . . . , xn) ,Sebuahk + 1= M1( ak, bk, ck,dk),bk+1=M0(ak,bk,ck,dk),ck+1=M−1(ak,bk,ck,dk),dk+1=M2(ak,bk,ck,dk)
Semua empat urutan konvergen ke nomor yang sama,MM(x1,x2,...,xn) .
Contoh
Mean Mean 1 dan 2 dihitung sebagai berikut: mulai dengan Sebuah0= ( 1 + 2 ) / 2 = 1.5 , b0= 1 ∗ 2----√= 2-√≈ 1.4142 ,c0= 211+ 12=43≈1.3333,d0=12+222−−−−−−−√=52−−√≈1.5811.
Kemudian
a1=1.5+1.4142+1.3333+1.58114≈1.4571,b1=1.5∗1.4142∗1.3333∗1.5811−−−−−−−−−−−−−−−−−−−−−−−√4≈1.4542,c1=411.5+11.4142+11.3333+11.5811≈1.4512,d1=1.52+1.41422+1.33332+1.581124−−−−−−−−−−−−−−−−−−−−−−−−−−−−√≈1.4601.
Perhitungan lebih lanjut dari urutan harus jelas. Dapat dilihat bahwa mereka bertemu ke nomor yang sama, kira-kira1.45568889.
Tantangan
Mengingat dua bilangan real positif, a dan b ( a<b ), menghitung mereka Berarti rata-rata MM(a,b) .
Uji kasus
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
Catatan
- Program Anda valid jika perbedaan antara output dan output yang benar tidak lebih besar dari 1/100000 dari nilai absolut perbedaan antara nomor input.
- Outputnya harus satu nomor.
Ini adalah kode-golf , jadi kode terpendek menang!
Jawaban:
Bahasa Wolfram (Mathematica) , 52 byte
Cobalah online!
Dalam pendekatan pertama saya, saya menggunakan builtin ini
Mean
GeometricMean
HarmonicMean
danRootMeanSquare
Berikut adalah beberapa penggantian untuk menghemat byte
HarmonicMean
->1/Mean[1/x]
oleh @Robin Ryder (3 byte disimpan)GeometricMean
->E^Mean@Log@x
oleh @A. Rex (2 byte disimpan)RootMeanSquare
->Mean[x^2]^.5
oleh @A. Rex (4 byte disimpan)akhirnya kami dapat menetapkan
Mean
untukM
(seperti yang diusulkan oleh @ovs) dan Hemat 5 byte lagisumber
#//.x_:>N@{Mean@x,E^Mean@Log@x,1/Mean[1/x],Mean[x^2]^.5}&
R,
706967 byteCobalah online!
-1 byte dengan pengkondisian yang lebih baik.
-2 byte dengan beralih ke basis 2.
Seperti beberapa jawaban lain, ini menggunakan ekspresi mean geometrik sebagai rata-rata aritmatika pada skala log (di sini dalam basis 2):M.0( x1, ... , xn) = 2M.1( log2x1, ... , log2xn).
Hal ini juga menggunakan fakta bahwa∀ k , dk≥ ak≥ bk≥ ck , yaitu dk= maks ( ak, bk, ck, dk) . Kondisi Sebuahk= bk= ck= dk Oleh karena itu setara dengan dk= M1( ak, bk, ck, dk) , yang saya gunakan di loop while; ini dicapai dengan menyalahgunakan sintaksck bukan karena merupakan minimal empat, tapi kami tidak bisa menggunakanSebuahk ataubk dalam kondisi.)
while
yang hanya mempertimbangkan elemen pertama ketika kondisinya adalah vektor, maka urutan penyimpanannya. (Perhatikan bahwa kita bisa juga menggunakanKetika kita keluar dari loop sementara,
x
adalah vektor konstan. Final?x
menghitung rata-rata untuk menguranginya menjadi skalar.sumber
J , 34 byte
(31 sebagai ekspresi tanpa penugasan ke variabel
f
)Cobalah online!
Untuk fungsi
a
danb
,a &.: b
("a di bawah b" ( tantangan terkait )) setara dengan(b inv) a b
- menerapkan b, lalu a, lalu kebalikan dari b. Dalam hal ini, rata-rata geometrik / harmonik / kuadrat adalah rata-rata aritmatika "di bawah", inversi, dan kuadrat.sumber
TI-BASIC,
423534 byte-1 byte terima kasih kepada @SolomonUcko
Input adalah daftar dua bilangan bulat di
Ans
.Output disimpan
Ans
dan dicetak secara otomatis ketika program selesai.Rumus yang digunakan untuk rata-rata geometris, harmonik, dan kuadrat didasarkan pada penjelasan user202729 .
Contoh:
Penjelasan:
(Baris baru telah ditambahkan untuk klarifikasi. Mereka TIDAK muncul dalam kode.)
Catatan:
TI-BASIC adalah bahasa tokenized. Jumlah karakter tidak sama dengan jumlah byte.
e^(
apakah ini token satu byte.^-1
digunakan untuk ini tanda satu-byte.Saya memilih untuk menulis
^-1
sebagai gantinya karena token terlihat sepertiֿ¹
ketika di blok kode.√(
apakah ini token satu byte.ΔList(
adalah ini tanda dua-byte.sumber
max(DeltaList(Ans
->variance(Ans
.Java 10,
234229214211215206203196180177 byte-5 byte terima kasih kepada @PeterCordes .
-15 byte lebih banyak berkat @PeterCordes , yang terinspirasi dari jawaban R @RobinRyder .
+4 byte karena saya berasumsi input sudah dipesan sebelumnya.
-27 byte terima kasih kepada @ OlivierGrégoire .
Cobalah online.
Penjelasan:
sumber
f+=Math.abs(d-D)<1e-9;
dan mendapatkan konversi implisit dari hasil perbandingan boolean ke integer 0/1 laludouble
. Apakah Java memiliki sintaks yang kompak untuk itu? Atau apakah mungkin untuk dilakukanf+=Math.abs(d-D)
dan kemudian memeriksa bahwa jumlah perbedaan absolut cukup kecil ?f>1e-8
berfungsi sebagai kondisi loop: 229 byte.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];}
. Dengan1e-9
, ini berjalan lebih lambat (sekitar dua kali waktu CPU), harus melakukan lebih banyak iterasi untuk mendapatkan 4 * pada dasarnyad-D
yang kecil. Dengan1e-7
, ini tentang kecepatan yang sama dengan 1e-8. Dengan1e-6
, beberapa digit tambahan berbeda untuk satu kasing.f
seluruhnya dan hanya memeriksaa[3]-a[2]<4e-9
.l==2||
maksud Anda ( golf tol<3|
). Tapi ya, poin bagus; Saya sudah menambahkannya. :)Arang , 40 byte
Cobalah online! Tautan adalah untuk mengucapkan versi kode. Mengambil input sebagai array angka. Penjelasan:
Ulangi sementara array berisi nilai yang berbeda ...
... ganti array dengan daftar nilai:
... yang berarti ...
... rerata geometris ...
... rata-rata harmonik ...
... dan root mean square.
Keluarkan elemen array ke string dan cetak secara implisit.
sumber
Jelly , 24 byte
Cobalah online!
sumber
PowerShell ,
182180183 byteCobalah online!
sumber
05AB1E ,
262423 byteCobalah secara online atau lihat langkah-langkah semua kasus uji .
-1 byte terima kasih kepada @Grimy .
23 byter alternatif untuk Geometric mean:
Cobalah secara online atau lihat langkah-langkah semua kasus uji .
Penjelasan:
sumber
Δ©P®gzm®ÅA®zÅAz®nÅAt)}н
Y
untuk 2/4. :)Δ©ÅA®.²ÅAo®zÅAz®nÅAt)}н
. Sayangnya, sepertinya kita tidak bisa memperbaiki semuaÅA
itu.Jelly ,
2524 byteCobalah online!
Penjelasan
sumber
P*İL
bekerja untuk arti geometris?P*Lİ$
jadi tidak akan menghemat byte. Itu berarti saya bisa membawaÆm
turun garis tanpa biaya byte, tapi saya cukup suka fakta masing-masing saat ini memiliki rata-rata aritmatika pada intinya.Python 3 , 152 byte
Cobalah online!
Fungsi rekursif
f
, akan menyatu dengan presisi floating point. Pada prinsipnya bekerja untuk semua daftar angka positif dari ukuran apa pun , tetapi dibatasi olehbatas rekursi Pythonkesalahan pembulatan untuk beberapa kasus uji.Atau, memilih presisi 9 desimal:
Python 3 , 169 byte
Cobalah online!
sumber
C # , 173 byte
Cobalah online!
sumber
using System
danusing System.Linq
dalam hitungan byte Anda, karena mereka diperlukan untuk menjalankan program. Anda dapat mengubah kompiler Anda menjadi C # Visual Interactive Compiler, yang tidak memerlukan impor itu. Juga,1.0
->1d
Bersihkan , 124 byte
Cobalah online!
Lakukan operasi sampai hasilnya berhenti berubah.
Hore untuk floating point presisi terbatas!
sumber
Pyth, 32 byte
Cobalah online di sini , atau verifikasi semua kasus uji (bilah dua, lihat catatan di bawah) sekaligus di sini . Menerima input sebagai daftar.
Tampaknya ada beberapa masalah dengan pembulatan, karena input tertentu tidak bertemu dengan benar ketika seharusnya tidak. Secara khusus, test case
0.01 100
macet pada nilai-nilai[6.748305820749738, 6.748305820749738, 6.748305820749739, 6.748305820749738]
, dan test case1.61 2.41
macet di[1.9896543776640825, 1.9896543776640825, 1.9896543776640827, 1.9896543776640825]
- perhatikan dalam kedua kasus bahwa rata-rata ke-3 (rata-rata harmonik) berbeda dari yang lain.Saya tidak yakin apakah masalah ini membatalkan entri saya, tetapi saya tetap mempostingnya karena seharusnya berfungsi. Jika ini tidak dapat diterima, itu dapat diperbaiki dengan menanamkan
.RRT
sebelum[
, untuk mengitari masing-masing sarana ke 10 tempat desimal, seperti yang terlihat dalam rangkaian uji ini .sumber
.Wt{H
denganu
untuk -4 byte (dan mengubahZ
keG
)Japt v2.0a0
-g
,4238 bytePasti ada jalan yang lebih pendek ... Ini adalah keburukan! Disimpan 4 byte berkat @Shaggy!
Cobalah
sumber
C # (Visual C # Interactive Compiler) , 177 byte
Terima kasih kepada @KevinCruijjsen karena menunjukkan bahwa menggunakan presisi floating point menyebabkan masalah! Akan menjadi 163 byte jika ganda itu sangat tepat.
Cobalah online!
sumber
StackOverflowException
ketelitian floating point. Alih-alihc==g[0]
Anda bisa melakukan sesuatu sepertiMath.Abs(c-g[0])<1e-9
. Cobalah online.kode mesin x86 (SIMD 4x float menggunakan 128-bit SSE1 & AVX) 94 byte
kode mesin x86 (SIMD 4x ganda menggunakan 256-bit AVX) 123 byte
float
lulus uji kasus dalam pertanyaan, tetapi dengan ambang loop-keluar cukup kecil untuk membuat itu terjadi, mudah untuk terjebak dalam loop tak terbatas dengan input acak.Instruksi presisi tunggal yang dikemas dengan SSE1 panjangnya 3 byte, tetapi instruksi SSE2 dan AVX sederhana sepanjang 4 byte. (Instruksi skalar-tunggal seperti
sqrtss
juga panjangnya 4 byte, itulah sebabnya saya menggunakansqrtps
meskipun saya hanya peduli pada elemen rendah. Bahkan tidak lebih lambat dari sqrtss pada perangkat keras modern). Saya menggunakan AVX untuk tujuan non-destruktif untuk menghemat 2 byte vs movaps + op.Dalam versi ganda kita masih dapat melakukan pasangan
movlhps
untuk menyalin potongan 64-bit (karena seringkali kita hanya peduli pada elemen rendah dari jumlah horizontal). Jumlah horisontal dari vektor 256-bit SIMD juga membutuhkan tambahanvextractf128
untuk mendapatkan setengah tinggi, vs strategi 2x lambat tapi kecilhaddps
untuk float . Itudouble
versi juga membutuhkan konstanta 2x 8-byte, bukannya 2x 4-byte. Secara keseluruhan itu keluar di dekat dengan 4/3 ukuranfloat
versi.mean(a,b) = mean(a,a,b,b)
untuk keempat cara ini , jadi kita bisa menduplikasi input hingga 4 elemen dan tidak pernah harus mengimplementasikan length = 2. Jadi, kita dapat hardcode geometric mean sebagai 4th-root = sqrt (sqrt), misalnya. Dan kita hanya perlu satu konstanta FP4.0
,.Kami memiliki vektor SIMD tunggal dari semua 4
[a_i, b_i, c_i, d_i]
. Dari itu, kami menghitung 4 berarti sebagai skalar dalam register terpisah, dan mengocoknya kembali untuk iterasi berikutnya. (Operasi horizontal pada vektor SIMD tidak nyaman, tetapi kita perlu melakukan hal yang sama untuk semua 4 elemen dalam cukup banyak kasus yang menyeimbangkan. Saya mulai pada versi x87 ini, tetapi sudah sangat lama dan tidak menyenangkan.)Kondisi loop-exit
}while(quadratic - harmonic > 4e-5)
(atau konstanta yang lebih kecil untukdouble
) didasarkan pada jawaban R @ RobinRyder , dan jawaban Java Kevin Cruijssen : mean kuadratik selalu merupakan besaran terbesar , dan mean harmonik selalu yang terkecil (mengabaikan kesalahan pembulatan). Jadi kita dapat memeriksa delta antara keduanya untuk mendeteksi konvergensi. Kami mengembalikan mean aritmatika sebagai hasil skalar. Biasanya antara keduanya dan mungkin yang paling rentan terhadap kesalahan pembulatan.Versi float : callable seperti
float meanmean_float_avx(__m128);
dengan nilai arg dan return di xmm0. (Jadi x86-64 System V, atau Windows x64 vectorcall, tetapi tidak x64 fastcall.) Atau nyatakan tipe-kembali sebagai__m128
sehingga Anda bisa mendapatkan kuadrat dan rata-rata harmonik untuk pengujian.Membiarkan ini mengambil 2
float
argumen terpisah dalam xmm0 dan xmm1 akan membutuhkan 1 byte tambahan: kita membutuhkan sebuahshufps
dengan imm8 (bukan hanyaunpcklps xmm0,xmm0
) untuk mengocok bersama dan menduplikasi 2 input.(Daftar NASM dibuat dengan
nasm -felf64 mean-mean.asm -l/dev/stdout | cut -b -34,$((34+6))-
. Strip bagian daftar dan memulihkan sumber dengancut -b 34- > mean-mean.asm
)Jumlah horizontal SIMD dan bagi dengan 4 (yaitu rata-rata aritmatika) diimplementasikan dalam fungsi terpisah yang kita
call
(dengan pointer fungsi untuk mengamortisasi biaya alamat). Dengan4/x
sebelum / sesudah, ataux^2
sebelum dan sesudah sqrt, kita mendapatkan mean harmonik dan rata-rata kuadratik. (Sungguh menyakitkan untuk menulisdiv
instruksi ini alih-alih mengalikannya dengan representasi yang tepat0.25
.)Mean geometrik diimplementasikan secara terpisah dengan multiprt dan dirantai sqrt. Atau dengan satu sqrt pertama untuk mengurangi besarnya eksponen dan mungkin membantu presisi numerik. log tidak tersedia, hanya
floor(log2(x))
melalui AVX512vgetexpps/pd
. Exp adalah semacam tersedia melalui AVX512ER (hanya Xeon Phi), tetapi dengan hanya 2 ^ -23 presisi.Mencampur instruksi AVX 128-bit dan warisan SSE bukan masalah kinerja. Mencampurkan 256-bit AVX dengan legacy SSE bisa di Haswell, tetapi di Skylake itu hanya berpotensi menciptakan ketergantungan palsu potensial untuk instruksi SSE. Saya pikir
double
versi saya menghindari rantai dep-loop yang tidak perlu dilakukan, dan kemacetan pada div / sqrt latency / throughput.Versi ganda:
Harness uji C
Dibangun dengan:
Tentunya Anda membutuhkan CPU dengan dukungan AVX, atau emulator seperti Intel SDE. Untuk mengkompilasi pada host tanpa dukungan AVX asli, gunakan
-march=sandybridge
atau-mavx
Jalankan: melewati kotak uji hard-coded, tetapi untuk versi float, kotak uji acak sering gagal
(b-a)/10000
ambang batas yang ditetapkan dalam pertanyaan.Kesalahan FP sudah cukup sehingga quad-harm keluar kurang dari nol untuk beberapa input.
Atau dengan
a += 1<<11; b += (1<<12)+1;
uncommented:Tak satu pun dari masalah ini terjadi
double
. Komentariprintf
sebelum setiap tes untuk melihat bahwa output kosong (tidak ada dariif(delta too high)
blok).TODO: gunakan
double
versi sebagai referensi untukfloat
versi, bukan hanya melihat bagaimana mereka konvergen dengan quad-harm.sumber
Javascript - 186 byte
Mengambil input sebagai array angka. Menggunakan transformasi rata-rata dalam jawaban J42161217 untuk mempersingkat kode.
Cobalah secara Online
Penjelasan
sumber
Perl 5 ,
9272 byteCobalah online!
... menggunakan beberapa trik kotor.
sumber
SNOBOL4 (CSNOBOL4) , 296 byte
Cobalah online!
Implementasi langsung. Menggunakan trik dari jawaban saya untuk pertanyaan terkait golf lebih banyak.
sumber