Gewichteter Durchschnitt - das Problem des Drucktrends

10

Nehmen wir an, dieses Array gibt an, wie viele Liegestütze ich in den letzten 28 Tagen jeden Tag gemacht habe:

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

Wie Sie sehen, hat es in der letzten Woche einen steilen Aufwärtstrend gegeben, und das ist der Teil dieser Daten, an dem ich am meisten interessiert bin. Je weiter in der Vergangenheit, desto weniger möchte ich, dass diese Daten in meinem Durchschnitt enthalten sind Anzahl der Liegestütze.

Zu diesem Zweck möchte ich einen „Durchschnitt“ ermitteln, bei dem jede Woche mehr wert ist als die vorherige Woche.


Hintergrundinformationen, die nicht Teil dieses Problems sind.

Normaler Durchschnitt:

Die Summe aller Werte / die Anzahl der Werte

Für oben:

1440/28 = 51,42857142857143


Gewichteter Durchschnitt:

Teilen Sie das Array in 4 7er-Gruppen auf und starten Sie ein neues Array.

  • Fügen Sie die erste Gruppe zum Array hinzu.
  • Fügen Sie die zweite Gruppe zweimal zum Array hinzu.
  • Fügen Sie die dritte Gruppe dreimal zum Array hinzu.
  • Fügen Sie die vierte Gruppe viermal zum Array hinzu.

Summiere das gesamte neue Array und dividiere durch die Länge des neuen Arrays.

Für oben:

Konvertieren Sie das Array in Folgendes:

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

Führen Sie dann einen normalen Durchschnitt für dieses Array aus.

4310/70 = 61,57142857142857

Beachten Sie, dass es aufgrund des Aufwärtstrends in der letzten Woche höher als der normale Durchschnittswert ist.


Die Regeln:

  • Die Eingabe ist ein flaches Array von 28 nichtnegativen Ganzzahlen.
  • Jede Sprache, in der Sie schreiben möchten.
  • Geben Sie eine Nummer aus.
  • Ich sehe immer gerne TIO- Links.
  • Versuchen Sie, das Problem in der kleinsten Anzahl von Bytes zu lösen.
  • Das Ergebnis sollte eine auf mindestens 4 Dezimalstellen genaue Dezimalstelle sein (entweder abgeschnitten oder aufgerundet von den Testfallwerten ist in Ordnung) oder ein exakter Bruch.

Testfälle:

Fall 1: Aufwärtstrend

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

Normaler Durchschnitt: 51.42857142857143 Gewichteter Durchschnitt: 61.57142857142857

Fall 2: Lassen Sie die Ruhe hinter sich

(Ich hatte eine schlechte Woche, aber es ist eine Weile her)

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

Normaler Durchschnitt: 40 Gewichteter Durchschnitt: 42

Fall 3: Aufgeben

Ich hatte eine schlechte Woche, es zieht meinen Durchschnitt schnell runter.

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

Normaler Durchschnitt: 40 Gewichteter Durchschnitt: 34

Fall 4: Mittelwertbildung

Okay, ich spiele hier nur herum, ich dachte, es könnte der gleiche Wert für den normalen und den gewichteten Durchschnitt sein, aber das war es natürlich nicht.

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

Normaler Durchschnitt: 31,25 Gewichteter Durchschnitt: 24,0


Bonusproblem:

Welche Kombination von 28 Werten hätte den gleichen normalen Durchschnitt und den gleichen gewichteten Durchschnitt?


Viel Spaß beim Golfen!

AJFaraday
quelle
Lassen Sie uns diese Diskussion im Chat fortsetzen .
AJFaraday
1
Vielleicht möchten Sie auch versuchen, exponentielle Glättung - new_avg = α*weekly_sum + (1-α)*old_avgfür einigeα∈(0,1)
Angs
2
Ich mache 0jeden Tag Liegestütze, daher ist mein gewichteter Durchschnitt der gleiche wie mein normaler Durchschnitt.
Neil
@Neil Sie würden nicht vom gewichteten Durchschnittssystem profitieren;)
AJFaraday
1
Achten Sie darauf, nicht zu überanstrengen: p
Brian H.

Antworten:

3

Schale , 6 Bytes

AΣΣṫC7

Probieren Sie es online aus!

Verwendet den Trick, mit dem Dennis meine Jelly-Vorlage übertroffen hat. Anstatt jeden Block N- mal zu wiederholen , werden die Suffixe der Liste der Blöcke abgerufen, die nach dem Reduzieren mit Ausnahme der Reihenfolge das gleiche Ergebnis liefern.

Mr. Xcoder
quelle
5

05AB1E , 8 7 Bytes

Dank Mr. Xcoder 1 Byte gespeichert

7ô.s˜ÅA

Probieren Sie es online aus!

Erläuterung

7ô         # split list into groups of 7
  .s       # push suffixes
    ˜      # flatten
     ÅA    # arithmetic mean
Emigna
quelle
@ Mr.Xcoder: Oh ja, ich wusste, dass ich eine mittlere Funktion gesehen hatte, aber ich konnte sie nicht finden: P
Emigna
4

Gelee , 7 Bytes

s7ṫJFÆm

Probieren Sie es online aus!

Wie es funktioniert

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
quelle
Huh, so x"J$ist das ṫJin diesem Zusammenhang gleichbedeutend . Interessant!
Mr. Xcoder
Art von. Anstatt die Elemente des n- ten Arrays n- mal zu wiederholen , werden alle Suffixe verwendet. Nach dem Reduzieren werden dieselben Elemente generiert, jedoch in einer anderen Reihenfolge.
Dennis
4

R + Pryr, 32 28 Bytes

und die gleiche durchschnittliche Punktzahl Woche für Woche würde zu einer Gleichheit der Mittel führen.

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

Probieren Sie es online aus!

Dank Giuseppe wurden 4 Bytes mithilfe des Punktprodukts gespeichert .

Pure R würde zwei weitere Bytes verwenden function

JayCe
quelle
Natürlich würde es, das ist so offensichtlich, jetzt denke ich darüber nach.
AJFaraday
1
28 Bytes mit Punktprodukt anstelle vonsum
Giuseppe
Ich hatte 40 Bytes mitfunction(s)weighted.mean(s,rep(1:4,e=7))
Giuseppe
1
@ Giuseppe Zum Glück erinnerte ich mich nicht weighted.mean. RIch liebe es, wenn Outgolfs Python.
JayCe
4

MATL , 10 Bytes

7es4:*s70/

Probieren Sie es online aus!

Ich habe seit Ewigkeiten keine MATL-Antwort mehr gepostet! Ich dachte, ich könnte im Rahmen von LOTM Mai 2018 teilnehmen !

Erläuterung:

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
quelle
Ich hatte auch K:7Y"*s70/bei 10 Bytes.
Giuseppe
3

Gelee , 9 Bytes

s7x"J$FÆm

Probieren Sie es online aus!

Wie es funktioniert

s7x "J $ FÆm - Übernimmt Eingaben vom ersten Befehlszeilenargument und gibt sie an STDOUT aus.
s7 - In 7er-Gruppen aufteilen.
   "- Vektorisiert auftragen (mit Reißverschluss):
  x J $ - Wiederholen Sie die Elemente jeder Liste mehrmals, die dem Index der Liste entsprechen.
      F - Abflachen.
       Æm - Arithmetisches Mittel.
Mr. Xcoder
quelle
2

Haskell , 35 Bytes

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

Bonus: Wenn a,b,c,des sich um die wöchentlichen Beträge handelt, entspricht der normale Durchschnitt dem gewichteten Durchschnitt, wenn:

(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

Eine Lösung ist, wenn die erste und die letzte Woche die gleichen Summen haben und die zweite und dritte Woche die gleiche Summe, aber es gibt unendlich viele Lösungen, wenn Ihr Bizeps dazu in der Lage ist. Beispiel: [15,10,10,10,10,10,5,20,20,20,25,25,20,20,30,20,20,20,20,20,20,20,10,10,20 0,10,10,10]

Probieren Sie es online aus!

Angs
quelle
2

JavaScript (Node.js) , 49 Byte

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

Probieren Sie es online aus!


Nicht generische Lösung

JavaScript (Node.js) , 39 36 Byte

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

Probieren Sie es online aus!

DanielIndie
quelle
1
-1 Byte bei der ersten Lösung mit a=>a.reduce((s,x,i)=>(I+=d=-~(i/7),s+x*d),I=0)/I. Und ein kurzer Tipp: Verwenden Sie <hr>, um eine horizontale Linie in Markdown zu erstellen
Herman L
@HermanL Was ist falsch an der Verwendung ---(benötigt einen eigenen Absatz)?
Neil
2

Stax , 10 8 Bytes

äΔ6◙█µøΓ

Führen Sie es aus und debuggen Sie es

Erklärung (ausgepackt):

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
quelle
1
Ein anderer mit Stax! Ja! Sie können $zum Reduzieren verwenden, wenn alle Elemente Ganzzahlen sind. Überprüfen Sie dies jetzt mit OP.
Khuldraeseth na'Barya
2

Holzkohle , 14 Bytes

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

Probieren Sie es online aus! Der Link führt zur ausführlichen Version des Codes. Erläuterung:

     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
quelle
2

K4 / K (oK) , 19 16 14 Bytes

Lösung:

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

Probieren Sie es online aus!

Beispiel:

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

Erläuterung:

Die Auswertung erfolgt von rechts nach links. Teilen Sie 7 1s, 7 2s, 7 3s und 7 4s durch 70 geteilt durch die Eingabe; dann fasse zusammen.

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

Excel: 33 Bytes

(3 Bytes, die aus der Antwort von @ wernisch gespeichert wurden, indem Daten auf 2 Zeilen von A1: N1 und A2: N2 ausgeführt wurden)

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

Entschuldigung, dass Sie dies nicht als Kommentar aufgenommen haben. Ich habe nicht genug Ruf dafür.

dissemin8or
quelle
2

Japt , 11 10 Bytes

xÈ/#F*ÒYz7

Versuch es


Erläuterung

 È             :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
Zottelig
quelle
1

Dreieckigkeit , 49 Bytes

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

Probieren Sie es online aus!

Erläuterung

)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.
Mr. Xcoder
quelle
1

Perl 5 -pa , 28 Bytes

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

Probieren Sie es online aus!

Die Eingabe ist eher durch Leerzeichen als durch Kommas getrennt.

Xcali
quelle
Sie haben $.als perfekten Multiplikator zur Verfügung. Keine Notwendigkeit für$i
Ton Hospel
1

APL + WIN, 13 Bytes

Fordert das Array als Vektor von ganzen Zahlen auf:

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

Erläuterung:

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
quelle
1

Java 8, 57 Bytes

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

Probieren Sie es online aus.

Erläuterung:

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
quelle
1

J , 16 Bytes

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

Erläuterung:

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

Probieren Sie es online aus!

Galen Ivanov
quelle
1

Clojure, 48 46 Bytes

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

Dies war kürzer als die Kombination aus Mapcat und Subvec.

NikoNyrh
quelle
1

TI-Basic, 25 Bytes

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

Alternative Lösung, 39 Bytes

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

Ruby , 65 Bytes

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

Probieren Sie es online aus!

lfvt
quelle
Die Eingabegröße wird hier auf 28 festgelegt. Sie können also mehrere Bytes sparen, indem Sie die Werte fest codieren, anstatt die sizeEigenschaft zu verwenden. Probieren Sie es online aus!
Sundar - Reinstate Monica
1

Excel, 36 33 Bytes

-3 Bytes dank @tsh.

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

Eingabe in der ersten Zeile ( A1bis AB1).

Wernisch
quelle
Vielleicht A1:AB1-> 1:1?
tsh
1

Julia 0,6 , 27 Bytes

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

Probieren Sie es online aus!

Der repeatAufruf bildet eine Spaltenmatrix mit 28 Werten, die sieben 'Einsen , dann sieben Zweien usw. enthält. Wir transponieren sie dann mit und führen dann eine Matrixmultiplikation mit der Eingabe durch (hier ist eine Multiplikation implizit). Da es sich um eine Matrixmultiplikation einer 1x28-Matrix mit einer 28x1-Matrix handelt, erhalten wir einen einzelnen Wert, der die gewichtete Summe ist, die wir benötigen. Teilen Sie das durch 70, um unseren gewichteten Mittelwert zu erhalten.

Sundar - Monica wieder einsetzen
quelle