isenção de responsabilidade: a média média é composta por mim
Defina a média aritmética de números como
Defina a média geométrica de números como
Defina a média harmônica de números como
Defina a média quadrática de números como
A média da média ( ) é definida da seguinte maneira: Defina quatro seqüências ( ) comonM1( x1, . . . , xn) = x1+ x2+ . . . + xnn
nM0 0( x1, . . . , xn) = x1x2. . . xn--------√n
nM- 1( x1, . . . , xn) = n1x2+ 1x2+ . . . + 1xn
nM2( x1, . . . , xn) = x21+ x22+ . . . + x2nn--------------√
MMumak, bk, ck, dkuma0 0= M1( x1, . . . , xn) ,b0 0= M0 0( x1, . . . , xn) ,c0 0= M- 1( x1, . . . , xn) ,d0 0= M2( x1, . . . , xn) ,umak + 1= M1( ak, bk, ck, dk) ,bk + 1= M0 0( ak, bk, ck, dk) ,ck + 1= M- 1( ak, bk, ck, dk) ,dk + 1= M2( ak, bk, ck, dk)
Todas as quatro seqüências convergem para o mesmo número, .MM( x1, x2, . . . , xn)
Exemplo
A média da média de 1 e 2 é calculada da seguinte forma: comece com
Então
O cálculo adicional das seqüências deve ser claro. Pode-se observar que eles convergem para o mesmo número, aproximadamente .uma0 0= ( 1 + 2 ) / 2 = 1,5 , b0 0= 1 ∗ 2----√= 2-√14 1.4142 ,c0 0= 211+ 12= 43≈ 1,3333 , d0 0= 12+ 222-------√= 52--√≈ 1,5811.
uma1= 1,5 + 1,4142 + 1,3333 + 1,5811445 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.
1.45568889
Desafio
Dados dois números reais positivos, e ( ), calcular a média média .umaba < bMM( a , b )
Casos de teste
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
Notas
- Seu programa é válido se a diferença entre a saída e a saída correta não for maior que 1/100000 do valor absoluto da diferença entre os números de entrada.
- A saída deve ser um único número.
Isso é código-golfe , então o código mais curto vence!
Respostas:
Wolfram Language (Mathematica) , 52 bytes
Experimente online!
Na minha primeira abordagem, usei esses componentes internos
Mean
GeometricMean
HarmonicMean
eRootMeanSquare
Aqui estão algumas substituições para salvar bytes
HarmonicMean
->1/Mean[1/x]
por @Robin Ryder (3 bytes salvos)GeometricMean
->E^Mean@Log@x
por @A. Rex (2 bytes salvos)RootMeanSquare
->Mean[x^2]^.5
por @A. Rex (4 bytes salvos)finalmente, podemos atribuir
Mean
aM
(como proposto por @ovs) e salvar mais 5 bytesfonte
#//.x_:>N@{Mean@x,E^Mean@Log@x,1/Mean[1/x],Mean[x^2]^.5}&
R,
706967 bytesExperimente online!
-1 byte com melhor condicionamento.
-2 bytes alternando para a base 2.
Como algumas outras respostas, isso usa a expressão da média geométrica como média aritmética na escala de log (aqui na base 2):M0(x1,…,xn)=2M1(log2x1,…,log2xn).
Ele também usa o fato de que , ou seja, . A condição é, portanto, equivalente a , que é o que eu uso no loop while; isso é conseguido abusando da sintaxe da qual considera apenas o primeiro elemento quando a condição é um vetor, daí a ordem na qual os meios são armazenados. (Observe que também poderíamos usar pois é o mínimo dos quatro, mas não poderíamos usar ou na condição.)∀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
Quando saímos do loop while,
x
é um vetor constante. O final?x
calcula sua média para reduzi-lo a um escalar.fonte
J , 34 bytes
(31 como uma expressão sem a atribuição à variável
f
)Experimente online!
Para funções
a
eb
,a &.: b
("a sob b" ( desafio relacionado )) é equivalente a(b inv) a b
- aplique b, então a, então inversa de b. Nesse caso, a média geométrica / harmônica / quadrática é a média aritmética "abaixo" do logaritmo, inversão e quadrado, respectivamente.fonte
TI-BASIC,
423534 bytes-1 byte graças a @SolomonUcko
Entrada é uma lista de dois números inteiros em
Ans
.A saída é armazenada
Ans
e impressa automaticamente quando o programa é concluído.As fórmulas usadas para médias geométricas, harmônicas e quadráticas são baseadas na explicação do usuário202729 .
Exemplo:
Explicação:
(Novas linhas foram adicionadas para esclarecimento. Elas NÃO aparecem no código.)
Notas:
TI-BASIC é uma linguagem tokenizada. Contagem de caracteres não é igual à contagem de bytes.
e^(
é esse token de um byte.^-1
é usado para este token de um byte.Optei por escrever,
^-1
porque o token parece estarֿ¹
em um bloco de código.√(
é esse token de um byte.ΔList(
é esse token de dois bytes.fonte
max(DeltaList(Ans
->variance(Ans
.Java 10,
234229214211215206203196180177 bytes-5 bytes graças a @PeterCordes .
-15 mais bytes graças a @PeterCordes , inspirado na resposta R. de @RobinRyder .
+4 bytes porque assumi que as entradas são pré-encomendadas.
-27 bytes graças a @ OlivierGrégoire .
Experimente online.
Explicação:
fonte
f+=Math.abs(d-D)<1e-9;
obter e obter uma conversão implícita de um resultado booleano de comparação para um número inteiro 0/1 e depoisdouble
. O Java tem alguma sintaxe compacta para isso? Ou é possível fazerf+=Math.abs(d-D)
e depois verificar se a soma das diferenças absolutas é pequena o suficiente?f>1e-8
funciona como uma condição de loop: 229 bytes.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];}
. Com1e-9
, ele roda mais devagar (cerca de duas vezes o tempo de CPU), tendo que fazer mais iterações parad-D
reduzir essencialmente 4 * esse tamanho. Com1e-7
, é aproximadamente a mesma velocidade que 1e-8. Com1e-6
, alguns dos dígitos finais diferem em um caso.f
completamente e apenas verificara[3]-a[2]<4e-9
.l==2||
você quer dizer ( jogou golfel<3|
). Mas sim, bom argumento; Eu adicionei. :)Carvão , 40 bytes
Experimente online! Link é a versão detalhada do código. Recebe a entrada como uma matriz de números. Explicação:
Repita enquanto a matriz contém valores diferentes ...
... substitua a matriz por uma lista de valores:
... O significativo...
... a média geométrica ...
... o meio harmônico ...
... e a raiz do quadrado médio.
Transmitir um elemento da matriz para string e imprimi-lo implicitamente.
fonte
Gelatina , 24 bytes
Experimente online!
fonte
PowerShell ,
182180183 bytesExperimente online!
fonte
05AB1E ,
262423 bytesExperimente online ou veja as etapas de todos os casos de teste .
-1 byte graças a @Grimy .
Alternativa de 23 bytes para a média geométrica:
Experimente online ou veja as etapas de todos os casos de teste .
Explicação:
fonte
Δ©P®gzm®ÅA®zÅAz®nÅAt)}н
Y
em 2/4. :)Δ©ÅA®.²ÅAo®zÅAz®nÅAt)}н
. Infelizmente, não parece que podemos refatorar todos essesÅA
s.Geléia ,
2524 bytesExperimente online!
Explicação
fonte
P*İL
funcionar para a média geométrica?P*Lİ$
para não salvar bytes. Isso significaria que eu poderia reduzirÆm
uma linha sem custar bytes, mas eu gosto bastante do fato de que cada uma atualmente possui uma média aritmética em seu núcleo.Python 3 , 152 bytes
Experimente online!
Função recursiva
f
, convergirá para precisão de ponto flutuante. Funciona em princípio para todas as listas de números positivos de qualquer tamanho, mas é limitado pelolimite de recursão do Python,um erro de arredondamento para alguns casos de teste.Como alternativa, resolvendo a precisão de 9 casas decimais:
Python 3 , 169 bytes
Experimente online!
fonte
C # , 173 bytes
Experimente online!
fonte
using System
eusing System.Linq
na sua contagem de bytes, pois eles são necessários para a execução do programa. Você pode alterar seu compilador para o C # Visual Interactive Compiler, que não precisa dessas importações. Além disso,1.0
->1d
Limpo , 124 bytes
Experimente online!
Executa a operação até que o resultado pare de mudar.
Hurrah para ponto flutuante de precisão limitada!
fonte
Pitão, 32 bytes
Experimente online aqui ou verifique todos os casos de teste (barra dois, veja a nota abaixo) de uma vez aqui . Aceita entrada como uma lista.
Parece haver alguns problemas com o arredondamento, pois certas entradas não convergem corretamente quando deveriam. Em particular, o caso de teste
0.01 100
fica preso em valores[6.748305820749738, 6.748305820749738, 6.748305820749739, 6.748305820749738]
e o caso de teste1.61 2.41
fica preso em[1.9896543776640825, 1.9896543776640825, 1.9896543776640827, 1.9896543776640825]
- observe nos dois casos que a terceira média (média harmônica) difere das outras.Não tenho certeza se esse problema invalida minha entrada, mas estou postando assim mesmo, pois deve funcionar. Se isso não for aceitável, pode ser corrigido inserindo
.RRT
antes de[
, para arredondar cada uma das médias para 10 casas decimais, como visto nesta suíte de testes .fonte
.Wt{H
comu
a -4 bytes (e mudançaZ
deG
)Japt v2.0a0
-g
,4238 bytesTem que haver um caminho mais curto ... Isso é uma monstruosidade! Guardado 4 bytes graças a @Shaggy!
Tente
fonte
C # (compilador interativo do Visual C #) , 177 bytes
Obrigado a @KevinCruijjsen por apontar que o uso da precisão de ponto flutuante estava causando problemas! Seriam 163 bytes se os dobros fossem perfeitamente precisos.
Experimente online!
fonte
StackOverflowException
precisão de ponto flutuante. Em vez dec==g[0]
você poderia fazer algo parecidoMath.Abs(c-g[0])<1e-9
. Experimente online.código de máquina x86 (float SIMD 4x usando SSE1 e AVX de 128 bits) 94 bytes
código de máquina x86 (SIMD 4x duplo usando AVX de 256 bits) 123 bytes
float
passa nos casos de teste da pergunta, mas com um limite de saída de loop pequeno o suficiente para que isso aconteça, é fácil ficar preso em um loop infinito com entradas aleatórias.As instruções de precisão única compactada do SSE1 têm 3 bytes de comprimento, mas as instruções SSE2 e AVX simples têm 4 bytes. (As instruções escalares únicas, como
sqrtss
também têm 4 bytes, é por isso que eu usosqrtps
mesmo que me importe apenas com o elemento baixo. Não é nem mais lento que o sqrtss no hardware moderno). Usei o AVX para destinos não destrutivos para economizar 2 bytes vs. movaps + op.Na versão dupla, ainda podemos
movlhps
copiar algumas partes de 64 bits (porque geralmente nos importamos apenas com o elemento baixo de uma soma horizontal). A soma horizontal de um vetor SIMD de 256 bits também exige um extravextractf128
para obter a metade alta, em comparação com a estratégia lenta, porém pequena, de 2xhaddps
para flutuação . odouble
A versão também precisa de constantes 2x de 8 bytes, em vez de 2x de 4 bytes. No geral, sai perto de 4/3 do tamanho dafloat
versão.mean(a,b) = mean(a,a,b,b)
para todos os quatro desses meios , para que possamos duplicar a entrada até 4 elementos e nunca ter que implementar length = 2. Assim, podemos codificar a média geométrica como quarta raiz = sqrt (sqrt), por exemplo. E nós só precisamos de uma constante FP4.0
,.Temos um único vetor SIMD de todos os 4
[a_i, b_i, c_i, d_i]
. A partir disso, calculamos as 4 médias como escalares em registros separados e as embaralhamos novamente para a próxima iteração. (As operações horizontais nos vetores SIMD são inconvenientes, mas precisamos fazer a mesma coisa para todos os 4 elementos em casos suficientes para equilibrar. Comecei em uma versão x87 disso, mas estava ficando muito longa e não divertida.)A condição de saída de loop de
}while(quadratic - harmonic > 4e-5)
(ou uma constante menor paradouble
) é baseada na resposta R de @ RobinRyder e na resposta Java de Kevin Cruijssen : média quadrática é sempre a maior magnitude e média harmônica é sempre a menor (ignorando erros de arredondamento). Portanto, podemos verificar o delta entre esses dois para detectar convergência. Retornamos a média aritmética como resultado escalar. Geralmente é entre os dois e é provavelmente o menos suscetível a erros de arredondamento.Versão flutuante : chamável como
float meanmean_float_avx(__m128);
no argumento arg e retorne o valor em xmm0. (Portanto, x86-64 System V ou Windows x64 vectorcall, mas não x64 fastcall.) Ou declare o tipo de retorno__m128
para que você possa obter a média quadrática e harmônica dos testes.Deixar isso levar dois
float
argumentos separados em xmm0 e xmm1 custaria 1 byte extra: precisaríamos de umshufps
com um imm8 (em vez de apenasunpcklps xmm0,xmm0
) para embaralhar e duplicar 2 entradas.(Listagem NASM criada com
nasm -felf64 mean-mean.asm -l/dev/stdout | cut -b -34,$((34+6))-
. Retire a parte da listagem e recupere a fontecut -b 34- > mean-mean.asm
)A soma e divisão horizontal SIMD por 4 (ou seja, média aritmética) é implementada em uma função separada que nós
call
(com um ponteiro de função para amortizar o custo do endereço). Com4/x
antes / depois, oux^2
antes e sqrt depois, obtemos a média harmônica e a média quadrática. (Foi doloroso escrever essasdiv
instruções em vez de multiplicá- las por uma representação exata0.25
).A média geométrica é implementada separadamente com sqrt multiplicado e encadeado. Ou com um sqrt primeiro para reduzir a magnitude do expoente e talvez ajudar na precisão numérica. o log não está disponível, apenas
floor(log2(x))
via AVX512vgetexpps/pd
. Exp está disponível via AVX512ER (somente Xeon Phi), mas com apenas 2 ^ -23 de precisão.A mistura de instruções AVX de 128 bits e SSE herdado não é um problema de desempenho. A mistura do AVX de 256 bits com o SSE herdado pode estar no Haswell, mas no Skylake, apenas cria uma potencial dependência falsa em potencial para as instruções do SSE. Acho que minha
double
versão evita cadeias de dep transportadas por loop desnecessárias e gargalos na latência / taxa de transferência div / sqrt.Versão dupla:
Arnês de teste C
Construa com:
Obviamente, você precisa de uma CPU com suporte a AVX ou de um emulador como o Intel SDE. Para compilar em um host sem suporte nativo ao AVX, use
-march=sandybridge
ou-mavx
Execução: passa nos casos de teste codificados, mas para a versão flutuante, os casos aleatórios geralmente falham no
(b-a)/10000
limite definido na pergunta.Os erros de FP são suficientes para que o dano quad seja menor que zero para algumas entradas.
Ou com não
a += 1<<11; b += (1<<12)+1;
comentado:Nenhum desses problemas ocorre com
double
. Comente oprintf
antes de cada teste para ver se a saída está vazia (nada doif(delta too high)
bloco).TODO: use a
double
versão como referência para afloat
versão, em vez de apenas ver como eles estão convergindo com dano quad.fonte
Javascript - 186 bytes
Recebe a entrada como uma matriz de números. Usa as transformações médias na resposta de J42161217 para encurtar o código.
Experimente Online
Explicação
fonte
Perl 5 ,
9272 bytesExperimente online!
... usando alguns truques sujos.
fonte
SNOBOL4 (CSNOBOL4) , 296 bytes
Experimente online!
Implementação direta. Usa um truque da minha resposta para uma pergunta relacionada ao golfe um pouco mais.
fonte