Moyenne pondérée - le problème de la tendance à la pression

10

Disons que ce tableau est le nombre de pressions que j'ai réalisées chaque jour au cours des 28 derniers jours:

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

Comme vous pouvez le voir, il y a eu une forte tendance à la hausse la semaine dernière, et c'est la partie de ces données qui m'intéresse le plus. Plus loin dans le passé, moins je veux que ces données figurent dans ma moyenne 'nombre de presses.

À cette fin, je veux établir une «moyenne» où chaque semaine vaut plus que la semaine précédente.


Les informations générales ne font pas partie de ce problème.

Moyenne normale:

La somme de toutes les valeurs / le nombre de valeurs

Pour ci-dessus:

1440/28 = 51,42857142857143


Moyenne pondérée:

Divisez le tableau en 4 groupes de 7 et démarrez un nouveau tableau.

  • Ajoutez le premier groupe au tableau.
  • Ajoutez le deuxième groupe au tableau deux fois.
  • Ajoutez le troisième groupe au tableau trois fois.
  • Ajoutez le quatrième groupe au tableau quatre fois.

Additionnez tout le nouveau tableau et divisez par la longueur du nouveau tableau.

Pour ci-dessus:

Convertissez le tableau en ceci:

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

Exécutez ensuite une moyenne normale sur ce tableau.

4310/70 = 61,57142857142857

Notez qu'il est supérieur à la valeur moyenne normale en raison de la tendance à la hausse de la semaine dernière.


Les règles:

  • L'entrée est un tableau plat de 28 entiers non négatifs.
  • N'importe quelle langue dans laquelle vous souhaitez écrire.
  • Sortez un nombre.
  • J'aime toujours voir les liens TIO .
  • Essayez de résoudre le problème dans le plus petit nombre d'octets.
  • Le résultat doit être une décimale précise à au moins 4 décimales (tronquée ou arrondie à partir des valeurs du scénario de test est très bien) ou une fraction exacte.

Cas de test:

Cas 1: tendance à la hausse

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

Moyenne normale: 51,42857142857143 Moyenne pondérée: 61,57142857142857

Cas 2: Laisser l'accalmie derrière

(J'ai eu une mauvaise semaine, mais c'était il y a longtemps)

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

Moyenne normale: 40 Moyenne pondérée: 42

Cas 3: abandonner

J'ai eu une mauvaise semaine, ça fait baisser ma moyenne rapidement.

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

Moyenne normale: 40 Moyenne pondérée: 34

Cas 4: Moyenne sur

D'accord, donc je joue juste ici, je pensais que ce pourrait être la même valeur pour les moyennes normales et pondérées, mais, bien sûr, ce n'était pas le cas.

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

Moyenne normale: 31,25 Moyenne pondérée: 24,0


Problème bonus:

Quelle combinaison de 28 valeurs aurait la même moyenne normale et la même moyenne pondérée?


Bon golf!

AJFaraday
la source
Continuons cette discussion dans le chat .
AJFaraday
1
Vous voudrez peut-être essayer le lissage exponentiel aussi - new_avg = α*weekly_sum + (1-α)*old_avgpour certainsα∈(0,1)
Angs
2
Je fais 0des tractions tous les jours, donc ma moyenne pondérée est la même que ma moyenne normale.
Neil
@Neil vous ne bénéficieriez pas du système de moyenne pondérée;)
AJFaraday
1
attention à ne pas surentraîner: p
Brian H.

Réponses:

3

Husk , 6 octets

AΣΣṫC7

Essayez-le en ligne!

Utilise l'astuce que Dennis a utilisé pour surpasser ma soumission Jelly. Au lieu de répéter chaque bloc N fois, il récupère les suffixes de la liste des blocs, ce qui après l'aplatissement donnera le même résultat, à l'exception de l'ordre.

M. Xcoder
la source
5

05AB1E , 8 7 octets

1 octet enregistré grâce à M. Xcoder

7ô.s˜ÅA

Essayez-le en ligne!

Explication

7ô         # split list into groups of 7
  .s       # push suffixes
    ˜      # flatten
     ÅA    # arithmetic mean
Emigna
la source
@ Mr.Xcoder: Oh ouais, je savais que j'avais vu une fonction moyenne, mais je ne l'ai pas trouvée: P
Emigna
4

Gelée , 7 octets

s7ṫJFÆm

Essayez-le en ligne!

Comment ça fonctionne

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
la source
Huh, x"J$est donc équivalent à ṫJdans ce contexte. Intéressant!
M. Xcoder
Sorte de. Au lieu de répéter les éléments du n -ième tableau n fois, cela prend tous les suffixes. Après aplatissement, il génère les mêmes éléments, mais dans un ordre différent.
Dennis
4

R + pryr, 32 28 octets

et le même score moyen semaine par semaine entraînerait l'égalité des moyennes.

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

Essayez-le en ligne!

Économisé 4 octets en utilisant le produit scalaire grâce à Giuseppe .

Pure R aurait deux octets supplémentaires en utilisant function

JayCe
la source
Bien sûr, ce serait tellement évident, maintenant j'y pense.
AJFaraday
1
28 octets en utilisant le produit scalaire au lieu desum
Giuseppe
J'ai eu 40 octets avecfunction(s)weighted.mean(s,rep(1:4,e=7))
Giuseppe
1
@Giuseppe Heureusement, je ne m'en souvenais pas weighted.mean. J'adore quand les Rgolfeurs Python.
JayCe
4

MATL , 10 octets

7es4:*s70/

Essayez-le en ligne!

Je n'ai pas posté de réponse MATL depuis des lustres! J'ai pensé que je pourrais participer dans le cadre de pensé LOTM mai 2018 !

Explication:

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
la source
J'avais aussi K:7Y"*s70/10 octets.
Giuseppe
3

Gelée , 9 octets

s7x"J$FÆm

Essayez-le en ligne!

Comment ça fonctionne

s7x "J $ FÆm - Prend les entrées du premier argument de ligne de commande et les sort vers STDOUT.
s7 - Divisé en groupes de 7.
   "- Appliquer vectorisé (zip avec):
  x J $ - Répète les éléments de chaque liste un nombre de fois égal à l'index de la liste.
      F - Aplatir.
       Æm - Moyenne arithmétique.
M. Xcoder
la source
2

Haskell , 35 octets

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

Bonus: si ce a,b,c,dsont les sommes hebdomadaires, la moyenne normale est la même que la moyenne pondérée ssi:

(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

Une solution est lorsque la première et la dernière semaine ont les mêmes sommes, ainsi que la deuxième et la troisième semaines ont la même somme, mais il existe une infinité de solutions si vos biceps sont à la hauteur. Exemple: [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]

Essayez-le en ligne!

Angs
la source
2

JavaScript (Node.js) , 49 octets

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

Essayez-le en ligne!


Solution non générique

JavaScript (Node.js) , 39 36 octets

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

Essayez-le en ligne!

DanielIndie
la source
1
-1 octet sur la première solution utilisant a=>a.reduce((s,x,i)=>(I+=d=-~(i/7),s+x*d),I=0)/I. Et un petit conseil: utilisez <hr>pour créer une ligne horizontale dans le démarque
Herman L
@HermanL Qu'est-ce qui ne va pas avec l'utilisation ---(a besoin de son propre paragraphe)?
Neil
2

Stax , 10 8 octets

äΔ6◙█µøΓ

Exécuter et déboguer

Explication (déballé):

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
la source
1
Un autre utilisant Stax! Oui! Vous pouvez utiliser $pour aplatir si les éléments sont tous des entiers, en vérifiant avec OP maintenant.
Khuldraeseth na'Barya
2

Fusain , 14 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

     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
la source
2

K4 / K (oK) , 19 16 14 octets

Solution:

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

Essayez-le en ligne!

Exemple:

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

Explication:

L'évaluation s'effectue de droite à gauche. Divisez 7 1s, 7 2s, 7 3s et 7 4s par 70 divisé par l'entrée; puis résumez.

+/(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
streetster
la source
2

Excel: 33 octets

(3 octets enregistrés à partir de la réponse de @ wernisch en exécutant des données sur 2 lignes de A1: N1 et A2: N2)

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

Toutes mes excuses pour ne pas avoir inclus cela en tant que commentaire. Je n'ai pas assez de réputation pour le faire.

diffus8or
la source
2

Japt , 11 10 octets

xÈ/#F*ÒYz7

Essayez-le


Explication

 È             :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
Hirsute
la source
1

Triangularité , 49 octets

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

Essayez-le en ligne!

Explication

)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.
M. Xcoder
la source
1

Perl 5 -pa , 28 octets

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

Essayez-le en ligne!

L'entrée est séparée par des espaces plutôt que par des virgules.

Xcali
la source
Vous disposez $.du multiplicateur parfait. Pas besoin de$i
Ton Hospel
1

APL + WIN, 13 octets

Demande le tableau comme vecteur d'entiers:

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

Explication:

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
la source
1

Java 8, 57 octets

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

Essayez-le en ligne.

Explication:

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
la source
1

J , 16 octets

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

Explication:

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

Essayez-le en ligne!

Galen Ivanov
la source
1

Clojure, 48 46 octets

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

Cela a fini par être plus court que la combinaison mapcat + subvec.

NikoNyrh
la source
1

TI-Basic, 25 octets

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

Solution alternative, 39 octets

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

Ruby , 65 octets

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

Essayez-le en ligne!

lfvt
la source
La taille d'entrée est spécifiée pour être fixée à 28 ici - vous pouvez donc enregistrer plusieurs octets en codant en dur les valeurs au lieu d'utiliser la sizepropriété. Essayez-le en ligne!
sundar
1

Excel, 36 33 octets

-3 octets grâce à @tsh.

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

Entrez dans la première ligne ( A1à AB1).

Wernisch
la source
Peut A1:AB1- être -> 1:1?
tsh
1

Julia 0.6 , 27 octets

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

Essayez-le en ligne!

L' repeatappel forme une matrice de colonnes de 28 valeurs, contenant sept 1, puis sept 2, etc. On le transpose ensuite avec ', puis on fait une multiplication matricielle avec l'entrée (la multiplication est implicite ici). Puisqu'il s'agit d'une multiplication matricielle d'une matrice 1x28 avec une matrice 28x1, nous nous retrouvons avec une seule valeur, qui est la somme pondérée dont nous avons besoin. Divisez cela par 70pour obtenir notre moyenne pondérée.

Sundar - Rétablir Monica
la source