Eine Reihe von Herausforderungen # 3: Moving Averages


16

Hinweis: Dies ist die Nummer 3 in einer Reihe von . Für die vorherige Herausforderung klicken Sie hier .

Gleitender Durchschnitt einer Liste

Der gleitende Durchschnitt einer Liste ist eine Berechnung, die zu einer neuen, geglätteten Liste führt, die durch Mitteln kleiner überlappender Unterlisten des Originals erstellt wird.

Bei der Erstellung eines gleitenden Durchschnitts wird zunächst die Liste der überlappenden Unterlisten mit einer bestimmten Fenstergröße erstellt, wobei dieses Fenster jedes Mal nach rechts verschoben wird.

Bei gegebener Liste [8, 4, 6, 2, 2, 4]und Fenstergröße 3wären die Unterlisten beispielsweise:

[8,  4,  6,  2,  2,  4]          Sublists:
(         )                  <-  [8, 4, 6]
    (         )              <-  [4, 6, 2]
        (         )          <-  [6, 2, 2]
            (         )      <-  [2, 2, 4]

Wir berechnen dann den Mittelwert jeder Unterliste, um das Ergebnis zu erhalten: [6.0, 4.0, 3.3, 2.7](jeder Wert wird auf eine Dezimalstelle gerundet).


Die Herausforderung

Ihre Aufgabe ist es, ein Programm oder eine Funktion zu schreiben, die bei gegebener Liste L und einer ganzen Zahl von 1 ≤ n ≤ Länge (L) den gleitenden Durchschnitt für L unter Verwendung der Fenstergröße n berechnet .

Regeln:

  • Ihr Programm kann eine Ganzzahl- oder eine Gleitkommadivision verwenden. Bei der Float-Division sind kleine Ungenauigkeiten aufgrund der Einschränkungen des Datentyps zulässig, sofern der Wert ansonsten korrekt ist.
  • Sie können ein vollständiges Programm oder eine Funktion (aber kein Ausschnitt) einreichen.
  • Sie können davon ausgehen, dass die Liste nur positive ganze Zahlen enthält .
  • Standardlücken sind verboten.
  • Das ist , also gewinnt die kürzeste Antwort (in Bytes)!

Testfälle

Beachten Sie, dass zur besseren Lesbarkeit alle Werte auf eine Dezimalstelle gerundet werden.

n=5, [1, 2, 3, 4, 5, 6, 7, 8]      ->      [3, 4, 5, 6]
n=3, [100, 502, 350, 223, 195]     ->      [317.3, 358.3, 256]
n=1, [10, 10, 10]                  ->      [10, 10, 10]
n=3, [10, 20, 30]                  ->      [20]
n=2, [90, 40, 45, 100, 101]        ->      [65, 42.5, 72.5, 100.5]

Müssen wir Float-Werte runden oder können wir sie so lassen, wie sie sind?
Caird Coinheringaahing

3
@cairdcoinheringaahing Beachten Sie, dass zur besseren Lesbarkeit alle Werte auf eine Dezimalstelle gerundet werden . Meiner Meinung nach können Sie sie definitiv so lassen, wie sie sind (zumindest verstehe ich das so).
Mr. Xcoder

@cairdcoinheringaahing Ich war ziemlich liberal mit I / O: Integer- oder Float-Werte sind in Ordnung, Sie können runden, wenn Sie wollen, aber nicht müssen, und Gleitkommafehler sind erlaubt
FlipTack

Ist es in Ordnung, Brüche anstelle von Gleitkommazahlen zurückzugeben?
JungHwan Min

@JungHwanMin Wenn Ihre Sprache aus Gründen der Genauigkeit Werte als Brüche und nicht als Gleitkommazahlen speichert, ist es in Ordnung, sie in ihrer einfachsten Form als genaue Brüche auszudrucken.
FlipTack

Antworten:





7

Dyalog APL, 4 Bytes

1 Byte gespeichert dank @Graham

2 Bytes gespart dank @ jimmy23013

Habe ich schon erwähnt, dass APL keine Golfsprache ist?

⊢+/÷

mit nrechts, oder

+/÷⊣

mit Lauf der rechten Seite.

Probieren Sie es online!

Wie?

÷- Teilen Ldurchn

⊢+/- Reduzieren Sie +auf Fenster vonn


Teilen Sie L vor der Reduktion durch n. Speichert ein Byte
Graham



@ Jimmy23013 vielen Dank! Ich habe es früher versucht, muss aber die Argumente falsch eingegeben haben, da es nicht funktioniert hat.
Uriel



4

Perl 6 , 33 Bytes

{@^a.rotor($^b=>1-$b)».sum X/$b}

Probier es aus

Erweitert:

{  # bare block with placeholder parameters 「@a」, 「$b」

  @^a                # declare and use first param

  .rotor(            # split it into chunks
    $^b              # declare and use second param
    =>               # pair it with
    1 - $b           # one less than that, negated

  )».sum             # sum each of the sub lists

  X/                 # cross that using &infix:«/»

  $b                 # with the second param
}

4

C  86   84  83 Bytes

i,j,s;f(a,l,n)int*a;{for(i=-1;i+++n<l;s=!printf("%d ",s/n))for(j=n;j--;)s+=a[i+j];}

Probieren Sie es online!

Abgerollt:

i, j, s;
f(a, l, n)int*a;
{
    for(i=-1; i+++n<l; s=!printf("%d ", s/n))
        for(j=n; j--;)
            s += a[i+j];
}

4

J, 7,5 Bytes

]+/\%

Probieren Sie es online!

Nimmt nals rechtes Argument und die Liste als linkes. Dank an Uriels Lösung für die Idee, nur die Summierung im Infix durchzuführen.

Erläuterung

]+/\%
    %  Divide list by n
]+/\   Sum on overlapping intervals of size n

Vorherige Lösung (7 Bytes)

(+/%#)\
      \  Apply to overlapping intervals of size n
(+/%#)   Mean
 +/        Sum
   %       Divided by
    #      Length



3

Oktave , 33 31 Bytes

@(x,n)conv(x,~~(1:n)/n,'valid')

Probieren Sie es online!

Erläuterung

Convolution ( conv) ist im Wesentlichen eine bewegte gewichtete Summe. Wenn die Gewichte als [1/n, ..., 1/n](erhalten als ~~(1:n)/n) gewählt werden, ist das Ergebnis ein gleitender Durchschnitt, von dem nur der 'valid'Teil beibehalten wird.


2

R , 72 Bytes

function(l,n)(k=sapply(0:sum(l|1),function(x)mean(l[x+1:n])))[!is.na(k)]

Probieren Sie es online!

Berechnet meandie Größe aller nFenster. Wenn das Fenster den Rand von überschreitet l, werden die Ergebnisse NAso herausgefiltert, dass wir sie herausfiltern.

R + Zoo-Paket, 13 Bytes

zoo::rollmean

Das zooPaket (S3-Infrastruktur für reguläre und unregelmäßige Zeitreihen) verfügt über viele praktische Funktionen. Sie können es hier versuchen (R-Geige) .


2

Japt v2.0a0, 7 Bytes

ãV ®x÷V

Versuch es


Erläuterung

Implizite Eingabe von Array Uund Ganzzahl V.

ãV

Holen Sie sich Unterabschnitte Umit LängeV

®

Karte über die Unterabschnitte.

÷V

Teilen Sie jedes Element durch V.

x

Summiere alle Elemente.




1

05AB1E , 5 Bytes

ŒsùÅA

Erläuterung:

Π    All substrings
 sù   Keep those only where the length is equal to <the second input>
   ÅA Arithmetic mean of each element in the resulting array.

Probieren Sie es online!





0

Jq 1,5 , 61 Bytes

def f(N;L):[L|range(0;1+length-N)as$i|.[$i:$i+N]|add/length];

Erweitert

def f(N;L):
  [   L
    | range(0;1+length-N) as $i        # generate
    | .[$i:$i+N]                       # sublists
    | add/length                       # compute mean
  ];

Probieren Sie es online!


0

JavaScript (ES6), 53 Byte

(l,n)=>l.map(e=>(s+=e-=a[i-n]||0)/n,s=i=0).slice(n-1)





0

K (oK) , 13 11 Bytes

Lösung:

{+/+x':y%x}

Probieren Sie es online!

Beispiele:

{+/+x':y%x}[3;8 4 6 2 2 4]
6 4 3.3333 2.6667
{+/+x':y%x}[5;1 2 3 4 5 6 7 8]
3 4 5 6

Erläuterung:

oK verfügt über eine integrierte Funktion zum Erstellen eines Schiebefensters. Fassen Sie die resultierenden Arrays zusammen und dividieren Sie sie durch die Größe des Schiebefensters, um den Mittelwert zu erhalten:

{+/+x':y%x} / the solution
{         } / lambda function taking x and y as implicit parameters
       y%x  / y (list) by x (sliding array size)
    x':     / sliding window of size x over list y
   +        / flip array (rotate by 90 degrees)
 +/         / sum up array

Sieht so aus, als ob Sie das Flip-Array + nicht benötigen. Wenn K wie APL pendelt, können Sie x%[commute]nach links gehen und die Parens ablegen
Uriel,

Die Flip benötigt die Summe ist , um sicherzustellen , über , anstatt nach unten jeder Liste, und ziemlich sicher , dass es kein pendeln Operator, zumindest nichts , um es in dem vorschlagen Handbuch . Prost aber!
Streetster

0

DataWeave , 50 Bytes

fun s(l,w)=0 to(sizeOf(l)-w)map avg(l[$ to $+w-1])
%dw 2.0
output application/json

fun sma(list: Array<Number>, window: Number) =
  0 to (sizeOf(list) - window)  // generate starting indices of sublists
  map list[$ to $ + window - 1] // generate sublists
  map avg($)                    // calculate averages

---
sma([90, 40, 45, 100, 101], 2)


0

Java 8, 111 Bytes

a->n->{int l=a.length-n+1,i=0,j;float[]r=new float[l];for(;i<l;r[i++]/=n)for(j=i;j<i+n;r[i]+=a[j++]);return r;}

Erläuterung:

Probieren Sie es hier aus.

a->n->{                 // Method with array and int parameters and float-array return-type
  int l=a.length-n+1,   //  New length of the return-array
      i=0,j;            //  Index-integers
  float[]r=new float[l];//  Return-array
  for(;i<l;             //  Loop (1) from 0 to `l` (exclusive)
      r[i++]/=n)        //    After every iteration, divide the current item by input `n`
    for(j=i;j<i+n;      //   Inner loop (2) from `i` to `i+n` (exclusive)
      r[i]+=a[j++]      //    Sum the result at index `i` with the items of the input-array
    );                  //   End of inner loop (2)
                        //  End of loop (1) (implicit / single-line body)
  return r;             //  Return the resulting float-array
}                       // End of method
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.