Promedio ponderado: el problema de la tendencia al presionar

10

Digamos que esta matriz es la cantidad de flexiones que he logrado cada día en los últimos 28 días:

[
  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 puede ver, ha tomado una fuerte tendencia al alza en la última semana, y esa es la parte de estos datos que más me interesa. Cuanto más en el pasado sea, menos quiero que esos datos aparezcan en mi promedio 'número de flexiones.

Con ese fin, quiero calcular un "promedio" donde cada semana valga más que la semana anterior.


Información de antecedentes, no es parte de este problema.

Promedio normal:

La suma de todos los valores / el número de valores

Por arriba:

1440/28 = 51.42857142857143


Peso promedio:

Divida la matriz en 4 grupos de 7 y comience una nueva matriz.

  • Agregue el primer grupo a la matriz.
  • Agregue el segundo grupo a la matriz dos veces.
  • Agregue el tercer grupo a la matriz tres veces.
  • Agregue el cuarto grupo a la matriz cuatro veces.

Suma toda la nueva matriz y divide por la longitud de la nueva matriz.

Por arriba:

Convierta la matriz a esto:

[
  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
]

Luego ejecute un promedio normal en esa matriz.

4310/70 = 61.57142857142857

Tenga en cuenta que es más alto que el valor promedio normal debido a la tendencia al alza en la última semana.


Las normas:

  • La entrada es una matriz plana de 28 enteros no negativos.
  • Cualquier idioma en el que te gustaría escribir.
  • Salida de un número.
  • Siempre me gusta ver enlaces TIO .
  • Intenta resolver el problema en el menor número de bytes.
  • El resultado debe ser un decimal exacto de al menos 4 decimales (ya sea truncado o redondeado a partir de los valores del caso de prueba está bien) o una fracción exacta.

Casos de prueba:

Caso 1: tendencia al alza

[
  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
]

Promedio normal: 51.42857142857143 Promedio ponderado: 61.57142857142857

Caso 2: Dejando atrás la calma

(Tuve una mala semana, pero fue hace un tiempo)

[
  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
]

Promedio normal: 40 Promedio ponderado: 42

Caso 3: Renunciar

Tuve una mala semana, está bajando mi promedio rápidamente.

[
  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
]

Promedio normal: 40 Promedio ponderado: 34

Caso 4: promediando

Bien, solo estoy jugando por aquí, pensé que podría ser el mismo valor para los promedios normales y ponderados, pero, por supuesto, no lo 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
]

Promedio normal: 31.25 Promedio ponderado: 24.0


Problema de bonificación:

¿Qué combinación de 28 valores tendría el mismo promedio normal y promedio ponderado?


¡Feliz golf!

AJFaraday
fuente
Continuemos esta discusión en el chat .
AJFaraday
1
Es posible que también desee probar el suavizado exponencial, new_avg = α*weekly_sum + (1-α)*old_avgpara algunosα∈(0,1)
Angs
2
Hago 0flexiones todos los días, por lo que mi promedio ponderado es el mismo que mi promedio normal.
Neil
@Neil no se beneficiaría del sistema de promedio ponderado;)
AJFaraday
1
tenga cuidado de no sobreentrenar: p
Brian H.

Respuestas:

3

Casco , 6 bytes

AΣΣṫC7

Pruébalo en línea!

Utiliza el truco que Dennis usó para superar mi presentación de Jelly. En lugar de repetir cada fragmento N veces, recupera los sufijos de la lista de fragmentos, que después del aplanamiento producirá el mismo resultado, excepto el orden.

Sr. Xcoder
fuente
5

05AB1E , 8 7 bytes

Guardado 1 byte gracias al Sr. Xcoder

7ô.s˜ÅA

Pruébalo en línea!

Explicación

7ô         # split list into groups of 7
  .s       # push suffixes
    ˜      # flatten
     ÅA    # arithmetic mean
Emigna
fuente
@ Mr.Xcoder: Oh, sí, sabía que había visto una función mala, pero no pude encontrarla: P
Emigna,
4

Jalea , 7 bytes

s7ṫJFÆm

Pruébalo en línea!

Cómo 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.
Dennis
fuente
Huh, entonces x"J$es equivalente a ṫJen este contexto. ¡Interesante!
Sr. Xcoder
Algo así como. En lugar de repetir los elementos de la n array-ésimo n veces, esto toma todos los sufijos. Después de aplanar, genera los mismos elementos, pero en un orden diferente.
Dennis
4

R + pryr, 32 28 bytes

y el mismo puntaje promedio semana tras semana daría como resultado la igualdad de los medios.

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

Pruébalo en línea!

Ahorro de 4 bytes mediante el uso del producto punto gracias a Giuseppe .

Pure R tendría dos bytes más usando function

JayCe
fuente
Por supuesto que sí, eso es tan obvio, ahora que lo pienso.
AJFaraday
1
28 bytes usando el producto punto en lugar desum
Giuseppe
Tenía 40 bytes confunction(s)weighted.mean(s,rep(1:4,e=7))
Giuseppe
1
@Giuseppe Por suerte no lo recordaba weighted.mean. Me encanta cuando los Routgolfs Python.
JayCe
4

MATL , 10 bytes

7es4:*s70/

Pruébalo en línea!

¡No he publicado una respuesta MATL en años! ¡Pensé que podría participar como parte de LOTM en mayo de 2018 !

Explicación:

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
James
fuente
Tenía K:7Y"*s70/10 bytes también.
Giuseppe
3

Jalea , 9 bytes

s7x"J$FÆm

Pruébalo en línea!

Cómo funciona

s7x "J $ FÆm - Toma la entrada del primer argumento de línea de comando y las salidas a STDOUT.
s7 - Dividir en grupos de 7.
   "- Aplicar vectorizado (zipwith):
  x J $ - Repite los elementos de cada lista varias veces igual al índice de la lista.
      F - Acoplar.
       Æm - Media aritmética.
Sr. Xcoder
fuente
2

Haskell , 35 bytes

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

Bonificación: si a,b,c,dson las sumas semanales, el promedio normal es el mismo que el promedio ponderado si:

(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

Una solución es cuando la primera y la última semana tienen las mismas sumas, y de la misma manera la segunda y la tercera semana tienen la misma suma, pero hay infinitas soluciones si sus bíceps están a la altura. Ejemplo: [15,10,10,10,10,10,5,20,20,20,25,25,20,20,30,20,20,20,20,20,20,10,10,20 , 0,10,10,10]

Pruébalo en línea!

Angs
fuente
2

JavaScript (Node.js) , 49 bytes

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

Pruébalo en línea!


Solución no genérica

JavaScript (Node.js) , 39 36 bytes

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

Pruébalo en línea!

DanielIndie
fuente
1
-1 byte en la primera solución usando a=>a.reduce((s,x,i)=>(I+=d=-~(i/7),s+x*d),I=0)/I. Y un consejo rápido: úselo <hr>para crear una línea horizontal en reducción
Herman L,
@HermanL ¿Qué tiene de malo usar ---(necesita su propio párrafo)?
Neil
2

Stax , 10 8 bytes

äΔ6◙█µøΓ

Ejecutar y depurarlo

Explicación (sin embalaje):

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
wastl
fuente
1
Otro usando Stax! ¡Si! Puede usar $para aplanar si los elementos son todos enteros, verifique con OP ahora.
Khuldraeseth na'Barya
2

Carbón , 14 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

     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
Neil
fuente
2

K4 / K (oK) , 19 16 14 bytes

Solución:

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

Pruébalo en línea!

Ejemplo:

+/(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

Explicación:

La evaluación se realiza de derecha a izquierda. Divida 7 1s, 7 2s, 7 3s y 7 4s entre 70 divididos por la entrada; entonces 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
callejero
fuente
2

Excel: 33 bytes

(3 bytes guardados de la respuesta de @ wernisch ejecutando datos en 2 líneas de A1: N1 y A2: N2)

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

Disculpas por no incluir esto como un comentario. No tengo suficiente reputación para hacerlo.

diseminar
fuente
2

Japt , 11 10 bytes

xÈ/#F*ÒYz7

Intentalo


Explicación

 È             :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
Lanudo
fuente
1

Triangularidad , 49 bytes.

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

Pruébalo en línea!

Explicación

)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.
Sr. Xcoder
fuente
1

Perl 5 -pa , 28 bytes

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

Pruébalo en línea!

La entrada está separada por espacios en lugar de por comas.

Xcali
fuente
Tienes $.disponible como el multiplicador perfecto. No es necesario$i
Ton Hospel
1

APL + WIN, 13 bytes

Solicita matriz como un vector de enteros:

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

Explicación:

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
Graham
fuente
1

Java 8, 57 bytes

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

Pruébalo en línea.

Explicación:

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
Kevin Cruijssen
fuente
1

J , 16 bytes

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

Explicación:

              #\           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

Pruébalo en línea!

Galen Ivanov
fuente
1

Clojure, 48 46 bytes

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

Esto terminó siendo más corto que la combinación mapcat + subvec.

NikoNyrh
fuente
1

TI-Basic, 25 bytes

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

Solución alternativa, 39 bytes.

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

Ruby , 65 bytes

->r{(b=(0..r.size/7).map{|a|r[a*7..-1]}.flatten).sum/b.size.to_f}

Pruébalo en línea!

lfvt
fuente
Aquí se especifica que el tamaño de entrada se fija en 28, por lo que puede guardar varios bytes codificando los valores en lugar de usar la sizepropiedad. Pruébalo en línea!
sundar - Restablecer Monica
1

Excel, 36 33 bytes

-3 bytes gracias a @tsh.

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

Entrada en primera fila ( A1a AB1).

Wernisch
fuente
Tal vez A1:AB1-> 1:1?
tsh
1

Julia 0.6 , 27 bytes

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

Pruébalo en línea!

La repeatllamada forma una matriz de columna de 28 valores, que contiene siete 1, luego siete 2, etc. Luego la transponemos ', luego hacemos una matriz de multiplicación con la entrada (la multiplicación está implícita aquí). Dado que es una multiplicación matricial de una matriz 1x28 con una matriz 28x1, terminamos con un solo valor, que es la suma ponderada que necesitamos. Divide eso entre 70para obtener nuestra media ponderada.

sundar - Restablecer a Monica
fuente