Média ponderada - o problema da tendência de pressup


10

Digamos que essa matriz seja a quantidade de flexões que realizei todos os dias nos últimos 28 dias:

[
  20,20,20,30,30,30,30,
  35,35,40,40,40,45,45,
  50,50,50,50,50,50,50,
  60,70,80,90,100,110,120
]

Como você pode ver, houve uma forte tendência de alta na última semana, e essa é a parte desses dados que mais me interessa. Quanto mais no passado, menos eu quero que esses dados apareçam na minha média 'número de flexões.

Para esse fim, quero elaborar uma "média" em que cada semana valha mais que a semana anterior.


Informações de plano de fundo, não fazem parte deste problema.

Média normal:

A soma de todos os valores / o número de valores

Para acima:

1440/28 = 51.42857142857143


Média ponderada:

Divida a matriz em 4 grupos de 7 e inicie uma nova matriz.

  • Adicione o primeiro grupo à matriz.
  • Adicione o segundo grupo à matriz duas vezes.
  • Adicione o terceiro grupo à matriz três vezes.
  • Adicione o quarto grupo à matriz quatro vezes.

Soma toda a nova matriz e divida pela duração da nova matriz.

Para acima:

Converta a matriz para isso:

[
  20,20,20,30,30,30,30, # first week once
  35,35,40,40,40,45,45, 
  35,35,40,40,40,45,45, # second week twice
  50,50,50,50,50,50,50,
  50,50,50,50,50,50,50,
  50,50,50,50,50,50,50, # third week thrice
  60,70,80,90,100,110,120,
  60,70,80,90,100,110,120,
  60,70,80,90,100,110,120,
  60,70,80,90,100,110,120 # Fourth week four times
]

Em seguida, execute uma média normal nessa matriz.

4310/70 = 61.57142857142857

Observe que é maior que o valor médio normal devido à tendência de alta na última semana.


As regras:

  • A entrada é uma matriz plana de 28 números inteiros não negativos.
  • Qualquer idioma em que você gostaria de escrever.
  • Saída de um número.
  • Eu sempre gosto de ver o TIO links .
  • Tente resolver o problema no menor número de bytes.
  • O resultado deve ser um decimal preciso com pelo menos 4 casas decimais (truncado ou arredondado dos valores dos casos de teste é bom) ou uma fração exata.

Casos de teste:

Caso 1: tendência ascendente

[
  20,20,20,30,30,30,30,
  35,35,40,40,40,45,45,
  50,50,50,50,50,50,50,
  60,70,80,90,100,110,120
]

Média normal: 51.42857142857143 Média ponderada: 61.57142857142857

Caso 2: deixando a pausa para trás

(Eu tive uma semana ruim, mas foi há um tempo)

[
  50,50,50,50,50,50,50,
  10,10,10,10,10,10,10,
  50,50,50,50,50,50,50,
  50,50,50,50,50,50,50
]

Média normal: 40 Média ponderada: 42

Caso 3: Desistir

Eu tive uma semana ruim, está diminuindo minha média rapidamente.

[
  50,50,50,50,50,50,50,
  50,50,50,50,50,50,50,
  50,50,50,50,50,50,50,
  10,10,10,10,10,10,10
]

Média normal: 40 Média ponderada: 34

Caso 4: Média da média

Ok, então estou apenas brincando por aqui, pensei que poderia ser o mesmo valor para as médias normais e ponderadas, mas, é claro, não era.

[
  60,60,60,60,60,60,60,
  30,30,30,30,30,30,30,
  20,20,20,20,20,20,20,
  15,15,15,15,15,15,15
]

Média normal: 31,25 Média ponderada: 24,0


Problema de bônus:

Que combinação de 28 valores teria a mesma média normal e média ponderada?


Feliz golfe!



11
Você pode querer tentar suavização exponencial também - new_avg = α*weekly_sum + (1-α)*old_avgpara algunsα∈(0,1)
Angs

2
Eu faço 0flexões todos os dias, então minha média ponderada é igual à minha média normal.
Neil

@Neil você não iria beneficiar do sistema de média ponderada;)
AJFaraday

11
tenha cuidado para não treinar demais: p
Brian H.

Respostas:


3

Casca , 6 bytes

AΣΣṫC7

Experimente online!

Usa o truque que Dennis usou para superar minha finalização em Jelly. Em vez de repetir cada pedaço N vezes, ele recupera os sufixos da lista de pedaços, que após o achatamento produzirão o mesmo resultado, exceto a ordem.



5

05AB1E , 8 7 bytes

Economizou 1 byte graças ao Sr. Xcoder

7ô.s˜ÅA

Experimente online!

Explicação

7ô         # split list into groups of 7
  .s       # push suffixes
    ˜      # flatten
     ÅA    # arithmetic mean

@ Mr.Xcoder: Oh sim, eu sabia que eu tinha visto uma função média, mas eu não poderia encontrá-lo: P
Emigna

4

Geléia , 7 bytes

s7ṫJFÆm

Experimente online!

Como funciona

s7ṫJFÆm  Main link. Argument: A (array of length 28)

s7       Split the array into chunks of length 7.
   J     Indices; yield [1, ..., 28].
  ṫ      Tail; yield the 1st, ..., 28th suffix of the result to the left.
         Starting with the 5th, the suffixes are empty arrays.
    F    Flatten the resulting 2D array.
     Æm  Take the arithmetic mean.

Huh, então x"J$é equivalente a ṫJneste contexto. Interessante!
Sr. Xcoder

Tipo de. Em vez de repetir os elementos da n- ésima matriz n vezes, isso leva todos os sufixos. Após achatar, gera os mesmos elementos, mas em uma ordem diferente.
Dennis

4

R + pryr, 32 28 bytes

e a mesma pontuação média semana após semana resultaria em igualdade dos meios.

pryr::f(s%*%rep(1:4,e=7)/70)

Experimente online!

Economizou 4 bytes usando o produto escalar graças a Giuseppe .

R puro teria mais dois bytes usando function


Claro que sim, isso é tão óbvio, agora penso nisso.
AJFaraday

11
28 bytes usando produto de ponto, em vez desum
Giuseppe

Eu tinha 40 bytes comfunction(s)weighted.mean(s,rep(1:4,e=7))
Giuseppe

11
@ Giuseppe Felizmente eu não me lembrava weighted.mean. Adoro quando Routgolfs Python.
JayCe

4

MATL , 10 bytes

7es4:*s70/

Experimente online!

Eu não postei uma resposta MATL em idades! Achei que eu poderia participar como parte de LOTM em maio de 2018 !

Explicação:

7e          % Reshape the array into 7 rows (each week is one column)
  s         % Sum each column
   4:       % Push [1 2 3 4]
     *      % Multiply each columnar sum by the corresponding element in [1 2 3 4]
      s     % Sum this array
       70/  % Divide by 70

Eu tinha K:7Y"*s70/10 bytes também.
Giuseppe

3

Geléia , 9 bytes

s7x"J$FÆm

Experimente online!

Como funciona

s7x "J $ FÆm - Retorna a entrada do primeiro argumento da linha de comando e gera para STDOUT.
s7 - Divida em grupos de 7.
   "- Aplicar vetorizado (zipwith):
  x J $ - Repita os elementos de cada lista várias vezes igual ao índice da lista.
      F - Achatar.
       Æm - Média aritmética.

2

Haskell , 35 bytes

(/70).sum.zipWith(*)([1..]<*[1..7])

Bônus: se a,b,c,dsão as somas semanais, a média normal é a mesma que a média ponderada se:

(a + b + c + d)/4 = (a + 2b + 3c + 4d)/10  <=>
10(a + b + c + d) = 4(a + 2b + 3c + 4d)    <=>
5(a + b + c + d)  = 2(a + 2b + 3c + 4d)    <=>
5a + 5b + 5c + 5d = 2a + 4b + 6c + 8d      <=>
3a + b - c - 3d   = 0

Uma solução é quando a primeira e a última semana têm as mesmas somas e a segunda e a terceira semana têm a mesma soma, mas existem infinitas soluções se o bíceps estiver à altura. Exemplo: [15,10,10,10,10,10,5,20,20,20,25,25,20,30,20,20,20,20,20,20,10,10,20,20 , 0,10,10,10]

Experimente online!


2

JavaScript (Node.js) , 49 bytes

a=>a.map((x,i)=>(I+=d=-~(i/7),s+=x*d),s=I=0)&&s/I

Experimente online!


Solução não genérica

JavaScript (Node.js) , 39 36 bytes

a=>a.reduce((s,x,i)=>s+x*-~(i/7))/70

Experimente online!


11
-1 byte na primeira solução usando a=>a.reduce((s,x,i)=>(I+=d=-~(i/7),s+x*d),I=0)/I. E uma dica rápida: use <hr>para criar uma linha horizontal em descontos
Herman L

@HermanL O que há de errado em usar ---(precisa de seu próprio parágrafo)?
Neil


2

Stax , 10 8 bytes

äΔ6◙█µøΓ

Execute e depure

Explicação (sem embalagem):

7/4R:B$:V Full program, implicit input
7/        Split into parts of length 7
  4R      Push [1, 2, 3, 4]
    :B    Repeat each element the corresponding number of times
      $   Flatten
       :V Average

11
Outro usando Stax! Sim! Você pode usar $para achatar se os elementos são todos números inteiros - verificando com OP agora.
Khuldraeseth na'Barya


2

Carvão , 14 bytes

I∕ΣE⪪A⁷×Σι⊕κ⁷⁰

Experimente online! Link é a versão detalhada do código. Explicação:

     A          Input array
    ⪪ ⁷         Split into subarrays of length 7
   E            Loop over each subarray
         ι      Subarray
        Σ       Sum
           κ    Loop index
          ⊕     Incremented
       ×        Product
  Σ             Sum results
            ⁷⁰  Literal 70
 ∕              Divide
I               Cast to string
                Implicitly print

2

K4 / K (oK) , 19 16 14 bytes

Solução:

+/(1+&4#7)%70%

Experimente online!

Exemplo:

+/(1+&4#7)%70%50 50 50 50 50 50 50 10 10 10 10 10 10 10 50 50 50 50 50 50 50 50 50 50 50 50 50 50
42

Explicação:

A avaliação é realizada da direita para a esquerda. Divida 7 1s, 7 2s, 7 3s e 7 4s por 70 dividido pela entrada; então resumir.

+/(1+&4#7)%70% / the solution               
           70% / 70 divided by the input
  (      )%    / the stuff in brackets divided by this...
      4#7      / draw from 7, 4 times => 7 7 7 7
     &         / 'where' builds 7 0s, 7 1s, 7 2s, 7 3s
   1+          / add one
+/             / sum (+) over (/) to get the total

2

Excel: 33 bytes

(3 bytes salvos da resposta de @ wernisch executando dados em 2 linhas de A1: N1 e A2: N2)

=AVERAGE(A1:N2,H1:N2,A2:N2,H2:N2)

Desculpas por não incluir isso como um comentário. Eu não tenho reputação suficiente para fazê-lo.


2

Japonês , 11 10 bytes

xÈ/#F*ÒYz7

Tente


Explicação

 È             :Pass each element at index Y through a function
  /#F          :  Divide by 70
       Yz7     :  Floor divide Y by 7
      Ò        :  Negate the bitwise NOT of that to add 1
     *         :  Multiply both results
x               :Reduce by addition

1

Triangularidade , 49 bytes

....)....
...D7)...
..14)21..
.WM)IEtu.
}u)70s/..

Experimente online!

Explicação

)D7)14)21WM)IEtu}u)70s/ – Full program.
)D7)14)21               – Push the literals 0, 7, 14, 21 onto the stack.
         WM     }       – Wrap the stack to a list and run each element on a separate
                          stack, collecting the results in a list.
           )IEt         – Crop the elements of the input before those indices.
               u        – Sum that list.
                 u      – Then sum the list of sums.
                  )70   – Push the literal 70 onto the stack.
                     s/ – Swap and divide.

1

Perl 5 -pa , 28 bytes

$\+=$_/70*int$i++/7+1for@F}{

Experimente online!

A entrada é separada por espaço em vez de separada por vírgula.


Você tem $.disponível como o multiplicador perfeito. Não há necessidade de$i
Ton Hospel

1

APL + WIN, 13 bytes

Solicita a matriz como um vetor de números inteiros:

(+/⎕×7/⍳4)÷70

Explicação:

7/⍳4) create a vector comprising 7 1s, 7 2s, 7 3s and 7 4s

+/⎕× prompt for input, multiply by the vector above and sum result

(....)÷70 divide the above sum by 70

1

Java 8, 57 bytes

a->{int r=0,i=35;for(;i-->7;)r+=i/7*a[i-7];return r/70d;}

Experimente online.

Explicação:

a->{              // Method with integer-array parameter and double return-type
  int r=0,        //  Result-sum, starting at 0
      i=35;       //  Index-integer, starting at 35
  for(;i-->7;)    //  Loop `i` downwards in the range (35,7]
    r+=           //   Add the following to the result-sum:
       i/7        //    `i` integer-divided by 7,
       *a[i-7];   //    multiplied by the item at index `i-7`
  return r/70d;}  //  Return the result-sum, divided by 70.0

1

J , 16 bytes

70%~1#.]*7#4{.#\

Explicação:

              #\           finds the lengths of all successive prefixes (1 2 3 4 ... 28)
           4{.             takes the first 4 items (1 2 3 4)
         7#                creates 7 copies of each element of the above list
       ]*                  multiplies the input by the above 
    1#.                    sum
70%~                       divide by 70

Experimente online!


1

Clojure, 48 46 bytes

#(/(apply +(for[i[0 7 14 21]v(drop i %)]v))70)

Isso acabou sendo mais curto que a combinação mapcat + subvec.


1

TI-Basic, 25 bytes

mean(Ansseq(sum(I>{0,7,21,42}),I,1,70

Solução alternativa, 39 bytes

Input L1
For(I,1,70
Ans+L1(I)sum(I>{0,7,21,42
End
Ans/70


1

Excel, 36 33 bytes

-3 bytes graças a @tsh.

=SUM(1:1,H1:AB1,O1:AB1,V1:AB1)/70

Entrada na primeira linha ( A1para AB1).


Talvez A1:AB1-> 1:1?
tsh

1

Julia 0.6 , 27 bytes

p->repeat(1:4,inner=7)'p/70

Experimente online!

A repeatchamada forma uma matriz de coluna de 28 valores, contendo sete 1's, depois sete 2's, etc. Nós 'a transpomos e depois fazemos uma multiplicação de matrizes com a entrada (a mutiplicação está implícita aqui). Como é uma multiplicação de matrizes de uma matriz 1x28 com uma matriz 28x1, acabamos com um único valor, que é a soma ponderada de que precisamos. Divida isso 70para obter nossa média ponderada.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.