Tablica wyzwań nr 3: Średnie kroczące


16

Uwaga: Jest to numer 3 w serii wyzwań dotyczących . Aby zobaczyć poprzednie wyzwanie, kliknij tutaj .

Średnia ruchoma listy

Średnia krocząca z listy jest obliczenie wyniku nowego, wygładzonej z listy, stworzonej przez uśrednienie małych listy zagnieżdżone nakładających oryginału.

Podczas tworzenia średniej ruchomej najpierw generujemy listę nakładających się podlist na podstawie pewnego „rozmiaru okna”, przesuwając to okno za każdym razem w prawo.

Na przykład, biorąc pod uwagę listę [8, 4, 6, 2, 2, 4]i rozmiar okna 3, listy podrzędne to:

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

Następnie obliczamy średnią średnią każdej podlisty, aby uzyskać wynik: [6.0, 4.0, 3.3, 2.7](każda wartość zaokrąglona do jednego miejsca po przecinku).


Wyzwanie

Twoim zadaniem jest napisanie programu lub funkcji, która, biorąc pod uwagę listę L i liczbę całkowitą 1 ≤ n ≤ długość (L) , oblicza średnią ruchomą dla L, używając rozmiaru okna n .

Zasady:

  • Twój program może używać podziału na liczby całkowite lub zmiennoprzecinkowe. W przypadku podziału zmiennoprzecinkowego dopuszczalne są małe niedokładności wynikające z ograniczeń typu danych, o ile wartość jest prawidłowa.
  • Możesz przesłać pełny program lub funkcję (ale nie fragment kodu).
  • Możesz założyć, że lista będzie zawierać tylko dodatnie liczby całkowite .
  • Standardowe luki są zabronione.
  • To jest , więc wygrywa najkrótsza odpowiedź (w bajtach)!

Przypadki testowe

Zauważ, że dla ułatwienia odczytu wszystkie wartości są zaokrąglane do jednego miejsca po przecinku.

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]

Czy musimy zaokrąglać wartości zmiennoprzecinkowe, czy możemy pozostawić je takimi, jakie są?
caird coinheringaahing

3
@cairdcoinheringaahing Pamiętaj, że dla ułatwienia odczytu wszystkie wartości są zaokrąglane do jednego miejsca po przecinku . Moim zdaniem zdecydowanie możesz zostawić je takimi, jakie są (przynajmniej tak rozumiem).
Pan Xcoder,

@cairdcoinheringaahing Byłem dość liberalny z I / O: wartości całkowite lub zmiennoprzecinkowe są w porządku, możesz zaokrąglać, jeśli chcesz, ale nie musisz, a błędy zmiennoprzecinkowe są dozwolone
FlipTack,

Czy można zwracać ułamki zamiast liczb zmiennoprzecinkowych?
JungHwan Min

@JungHwanMin Jeśli dla zachowania dokładności Twój język będzie przechowywać wartości jako ułamki, a nie liczby zmiennoprzecinkowe, dobrze jest wydrukować je jako dokładne ułamki w ich najprostszych postaciach.
FlipTack,

Odpowiedzi:




7

Haskell , 47 bajtów

n!a|length a<n=[]|_:t<-a=div(sum$take n a)n:n!t

Wypróbuj online!

Zaoszczędzono dwa bajty dzięki xnor!


1
tail amożna wyciągnąć na straży.
xnor

Gah, wiedziałem, że czegoś mi brakuje. Dziękuję Ci!
Lynn,

7

Dyalog APL, 4 bajty

1 bajt zapisany dzięki @Graham

2 bajty zapisane dzięki @ jimmy23013

Czy wspominałem, że APL nie jest językiem golfowym?

⊢+/÷

z npo prawej stronie lub

+/÷⊣

z Lpo prawej.

Wypróbuj online!

W jaki sposób?

÷- podziel Lprzezn

⊢+/- zmniejszyć +na oknachn


Dlaczego nie podzielić L przez n przed redukcją. Zapisuje bajt
Graham



@ jimmy23013 dzięki bardzo! Próbowałem tego wcześniej, ale musiałem wpisać niewłaściwe argumenty, bo to nie zadziałało.
Uriel,

6

Python , 48 bajtów

f=lambda n,l:l[n-1:]and[sum(l[:n])/n]+f(n,l[1:])

Wypróbuj online!

Funkcja rekurencyjna. Krótszy niż program (50 bajtów)

n,l=input()
while l[-n]:print sum(l[:n])/n;l=l[1:]

Wypróbuj online!

Oszczędza to 2 bajty, kończąc z błędem whilewarunek.



4

Perl 6 , 33 bajtów

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

Sprawdź to

Rozszerzony:

{  # 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 bajtów

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];}

Wypróbuj online!

Rozwinięty:

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 bajtów

]+/\%

Wypróbuj online!

Przyjmuje nza prawy argument, a listę za lewą. Podziękowania dla rozwiązania Uriela za pomysł wykonania tylko podsumowania w infixie.

Wyjaśnienie

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

Poprzednie rozwiązanie (7 bajtów)

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


3

Pyth , 5 bajtów

.O.:F

Wypróbuj tutaj!

Jak to działa

.O.: F - Pełny program.

    F - Zmniejsz dane wejściowe (lista zagnieżdżona) za pomocą ...
  .: - ... Podlisty.
.O - średnia każdego.

3

Oktawa , 33 31 bajtów

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

Wypróbuj online!

Wyjaśnienie

Convolution ( conv) jest zasadniczo ruchomą sumą ważoną. Jeśli wagi zostaną wybrane jako [1/n, ..., 1/n](uzyskane jako ~~(1:n)/n), wynikiem będzie średnia ruchoma, z której zachowana zostanie tylko 'valid'część.


2

R , 72 bajty

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

Wypróbuj online!

Oblicza meanwszystkie nokna wielkości ; gdy okno mija krawędź l, wyniki są NAtak, że je odfiltrowujemy.

Pakiet R + zoo, 13 bajtów

zoo::rollmean

The zooPakiet (infrastruktura S3 dla regularnych i nieregularnych szeregów czasowych) posiada wiele funkcji przydatnych. Możesz spróbować tutaj (skrzypce R) .


2

Japt v2.0a0, 7 bajtów

ãV ®x÷V

Spróbuj


Wyjaśnienie

Domniemane wprowadzanie tablicy Ui liczby całkowitej V.

ãV

Uzyskaj podsekcje Uo długościV

®

Mapuj podsekcje.

÷V

Podziel każdy element przez V.

x

Zsumuj wszystkie elementy.




1

05AB1E , 5 bajtów

ŒsùÅA

Wyjaśnienie:

Œ     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.

Wypróbuj online!





0

Jq 1,5 , 61 bajtów

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

Rozszerzony

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

Wypróbuj online!


0

JavaScript (ES6), 53 bajty

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





0

K (oK) , 13 11 bajtów

Rozwiązanie:

{+/+x':y%x}

Wypróbuj online!

Przykłady:

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

Wyjaśnienie:

oK ma wbudowane okno przesuwne, a następnie zsumuj wynikowe tablice i podziel przez rozmiar przesuwanego okna, aby uzyskać średnią:

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

Wygląda na to, że nie potrzebujesz tablicy flip +, a jeśli K dojeżdża do pracy jak APL, możesz przejść x%[commute]w lewo i upuścić pareny
Uriel

Odwrócenie jest potrzebne, aby suma była w poprzek, a nie w dół na każdej liście, i dość pewna, że ​​nie ma operatora dojeżdżania do pracy, a przynajmniej nic, co sugeruje to w instrukcji . Na zdrowie!
streetster,

0

DataWeave , 50 bajtów

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 bajtów

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;}

Wyjaśnienie:

Wypróbuj tutaj.

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.