Umlaufende Summe


24

Inspiriert von einer Frage bei Stack Overflow .

Berechnen Sie bei einem nicht leeren Array von Ganzzahlen xund einer positiven Ganzzahl ndie Summe der einzelnen Gleitblöcke mit der Länge ndes Arrays x, und füllen Sie die fehlenden Werte links zirkulär mit Werten von rechts wie folgt:

  • Der erste Block enthält den ersten Eintrag von x, dem n-1zirkulär verschobene Einträge vorangestellt sind .
  • der zweite Block hat die ersten und zweiten Einträge von x, denen n-2zirkulär verschobene Einträge vorausgehen ; und so weiter.

Das Ausgabearray yhat die gleiche Größe wie x. Es ist möglich n, die Länge von zu überschreiten x, und dann werden die Werte von mehrmalsx zirkulär wiederverwendet .

Beispiele

Beispiel 1 (Werte werden nur einmal verwendet)

x = [2, 4, -3, 0, -4]
n = 3

als Ausgabe geben

y = [-2, 2, 3, 1, -7]

woher

  • -2ist die Summe des Blocks [0, -4, 2](die ersten beiden Werte stammen aus der zirkularen Verschiebung)
  • 2ist die Summe von [-4, 2, 4](der erste Wert ergibt sich aus der zirkularen Verschiebung)
  • 3ist die Summe von [2, 4, -3](keine zirkuläre Verschiebung mehr notwendig)
  • 1 ist die Summe von [4, -3, 0]
  • -7ist die Summe von [-3, 0, -4].

Beispiel 2 (Werte werden mehrfach wiederverwendet)

x = [1, 2]
n = 5

geben

y = [7, 8]

woher

  • 7ist die Summe des Blocks [1, 2, 1, 2, 1](die ersten vier Werte wurden zirkulär wiederverwendet)
  • 8ist die Summe des Blocks [2, 1, 2, 1, 2](die ersten drei Werte wurden zirkulär wiederverwendet)

Zusätzliche Regeln

  • Der Algorithmus sollte für Arrays beliebiger Größe und für beliebige ganzzahlige Werte funktionieren. Es ist akzeptabel, wenn das Programm durch Datentyp- oder Speicherbeschränkungen eingeschränkt ist. Es müssen jedoch sowohl positive als auch negative ganzzahlige Werte behandelt werden.
  • Input / Output kann auf jede vernünftige Weise genommen / produziert werden .
  • Programme oder Funktionen sind in jeder Programmiersprache zulässig . Standardlücken sind verboten.
  • Kürzester Code in Bytes gewinnt.

Testfälle

x, n, -> y

[2, 4, -3, 0, -4], 3          ->  [-2, 2, 3, 1, -7]
[1, 2], 5                     ->  [7, 8]
[2], 7                        ->  [14]
[-5, 4, 0, 1, 0, -10, -4], 4  ->  [-19, -15, -5, 0, 5, -9, -13]
[-5, 4, 0, 1, 0, -10, -4], 1  ->  [-5, 4, 0, 1, 0, -10, -4]
[-2, -1, 0, 1, 2, 3], 5       ->  [4, 3, 2, 1, 0, 5]
[-10, 0, 10], 4               ->  [-10, 0, 10]

6
Bah, warum musstest du vorhergehende Einträge verwenden?
Neil

Antworten:


3

Gelee , 5 Bytes

ṙC€}S

Probieren Sie es online!

Wie es funktioniert

ṙC€}S  Main link. Arguments: A (array), n (positive integer)

   }   Apply the link to the left to the right argument (n).
 C€      Complement each; map (z -> 1-z) over [1, ..., n], yielding [0, ..., 1-n].
ṙ      Rotate A 0, ..., 1-n units to the left (i.e., 0, ..., n-1 units to the
       right), yielding a 2D array.
    S  Take the sum of the rows.

7

MATL, 11 10 9 7 Bytes

3 Bytes gespart dank @Luis!

:gyn&Z+

Die erste Eingabe ist die Größe des Fensters und die zweite Eingabe ist das Array

Probieren Sie es bei MATL Online aus

Erläuterung

       % Implicitly grab the first input (n)
       %     STACK: { 3 }
:      % Create the array [1...n]
       %     STACK: { [1, 2, 3] }
g      % Convert it to a logical array, yielding an array of 1's of length n
       %     STACK: { [1, 1, 1] }
y      % Implicitly grab the second input and duplicate it
       %     STACK: { [2, 4, -3, 0, -4], [1, 1, 1], [2, 4, -3, 0, -4]}
n      % Determine the length of the array
       %     STACK: { [2, 4, -3, 0, -4], [1, 1, 1], 5}
&Z+    % Perform circular convolution
       %     STACK: { [-2, 2, 3, 1, -7] }
       % Implicitly display the result

6

Mathematica, 29 Bytes

RotateLeft[#,1-n]~Sum~{n,#2}&

Oder gleich lang:

ListConvolve[1~Table~#2,#,1]&

6

CJam (16 Bytes)

{_2$*ew1fb\,~)>}

Online-Testsuite . Dies ist ein anonymer Block (eine Funktion), der das Array und die Länge auf dem Stapel übernimmt und ein Array auf dem Stapel belässt.

Präparation

{       e# Declare a block
  _2$*  e#   Repeat the array n times: this guarantees having enough windows even
        e#   if x is only a single element
  ew    e#   Take each window of n elements
  1fb   e#   Sum each of the windows
  \,~)  e#   Compute -n
  >     e#   Take the last n elements of the array of sums
}

4

Haskell, 57 Bytes

a#n|l<-length a=[sum[a!!mod j l|j<-[i-n..i-1]]|i<-[1..l]]

Probieren Sie es online!

Nur einige Indexschleifen und der Zugriff auf die Eingabeliste bei Indizes modulieren die Länge der Liste.


3

Haskell , 69 65 64 Bytes

r=reverse
s#n=r$init[sum$take n$x++cycle(r s)|x<-scanr(:)[]$r s]

Probieren Sie es online! Beispiel Nutzung: [2, 4, -3, 0, -4] # 3.


Die Verwendung von n erfolgreichen anstelle von vorhergehenden Einträgen kann 50 bis 46 Byte umfassen (das Gegenteil am Anfang und am Ende wird entfernt):

s#n=init[sum$take n$x++cycle s|x<-scanr(:)[]s]

Probieren Sie es online!



2

Pyth , 18 16 Bytes

2 Bytes gespart dank @FryAmTheEggman !

JEms<.>*JQ-JhdJl

Probieren Sie es hier aus oder überprüfen Sie alle Testfälle.

Alle Fehler wurden mit einem Preis von -6 Bytes behoben ! Vielen Dank an Luis, der mir die Aufgabe im Chat erklärt hat.


Erklärung (zu aktualisieren)

KEms<>_*QhK-lQhdKU - Full program.

KE                 - Assign the second input to a variable K.
  m              U - Map over the range [0...len(first input)).
       *QhK        - First input * (Second input + 1).
      _            - Reverse.
     >     -lQhd   - All the elements of the above after len(x)-current element-1
    <          K   - Up until the second input.
   s               - Sum.

Könnte ein besserer Weg sein, bevor Sie rückwärts fahren und versuchen, bald Golf zu spielen.
Mr. Xcoder

Ich habe 16 Bytes, aber ich denke, es sollte noch etwas kürzeres geben.
FryAmTheEggman

@FryAmTheEggman Danke. Ich finde, es sollte kürzer sein, aber ich kann nicht herausfinden, wie
Mr. Xcoder

2

Java 8, 102 Bytes

Lambda (Curry) von int[]bis Lambda von Integerbis int[]. Zuweisen zu Function<int[], Function<Integer, int[]>>.

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

Probieren Sie es online

Ungolfed Lambda

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

(j % l + l) % lberechnet einen nichtnegativen Rest für any j. Von hier genommen .



2

Oktave, 53 Bytes

@(x,n)shift(imfilter(x,+!!(1:n),'circular'),fix(n/2))

Probieren Sie es online!

  • Die imfilterFunktion mit Option circularberechnet die kreisförmige Faltung in der Mitte des Fensters, sodass das Ergebnis verschoben werden sollte.

2

05AB1E , 10 Bytes

.׌ùOR¹g£R

Probieren Sie es online!

Erläuterung

.×           # repeat input_1 input_2 times
  Ν         # push all sublists of size input_2
    O        # sum each
     R       # reverse the list
      ¹g£    # take the first len(input_1) items
         R   # reverse the list

2

Perl 6 , 42 39 Bytes

{@^a;[«+»] map {@a.rotate(-$_)},^$^b}

Probieren Sie es online!

Mein erster Perl 6 Eintrag. Kann wohl verbessert werden.


Beachten Sie, dass Sie manchmal die Länge unter Verwendung eines spitzen Blockes mit sigilless Variablen eher als ein Block mit Platzhalter Parametern reduzieren können ->\a,\b{[«+»] map {a.rotate(-$_)},^b}Beachten Sie, dass es in diesem Fall nicht tut , aber es wäre , wenn es eine andere Instanz $bim Code.
Brad Gilbert b2gills

2

Kotlin , 141 140 138 Bytes

Nur ein erster Versuch

Einreichung

fun c(a:List<Int>,n:Int):List<Int>{
return (0..(a.size-1)).map{var t=0
for (o in 0..(n-1)){var i=it-o
while(i<0) {i+=a.size};t+=a[i]}
t}}

Verschönert

fun c(a: List<Int>, n: Int): List<Int> {
    return (0..(a.size - 1)).map {    // Iterate over the items
        var t = 0                     // Start the total at 0
        for (o in 0..(n - 1)) {       // Start at the item, go over the window backwards
            var i = it - o            // -------------------------
            while (i < 0) {           //  Make the index in range
                i += a.size           //
            }                         // -------------------------
            t += a[i]                 // Add the item to the total
        }
        t                             // Return the total
    }
}

TryItOnline

Bearbeitungen

  • Zeilenvorschub an der letzten schließenden Klammer entfernt

1

Röda , 52 Bytes

f a,n{(a*n)|slide n|tail#a*n|{head n|sum}while open}

Probieren Sie es online!

Erläuterung:

f a,n{
  (a*n)|    /* Push the items in a n times to the stream */
  slide n|  /* Create a sliding block of length n */
  tail#a*n| /* Push the last n*len(a) values in the stream to the stream */
  {         /* While there are elements in the stream (stream is open): */
    head n| /*   Pull n values from the stream */
    sum     /*   Sum them and push the sum to the stream */
  } while open
}

1

JavaScript ES6 80 78 Bytes

x=>n=>x.map((_,i)=>eval('for(L=x.length,N=0,j=++i-n;j<i;j++)N+=x[(j%L+L)%L]'))

2 Bytes gespart dank Neil

Verwendung:

f=x=>n=>x.map((_,i)=>eval('for(L=x.length,N=0,j=++i-n;j<i;j++)N+=x[(j%L+L)%L]'))

f([2, 4, -3, 0, -4])(3)

1
Das ,Nsieht für mich unnötig aus ...
Neil

@ Neil Du hast recht, danke
Bálint


1

Python 2 , 69 61 Bytes

- 8 Bytes Vielen Dank @muru

lambda x,n:[sum((x[-n+1:]+x*n)[i:i+n])for i in range(len(x))]

Probieren Sie es online!

Erläuterung:

Zuerst müssen wir sicherstellen, dass links von der ursprünglichen Liste genügend Nummern vorhanden sind. Dies wird durch die erreicht x*n+x Teil erreicht.

Zum Beispiel [2,4,-3,0,4],5:

                   ,2,4,-3,0,-4
 ....-4,2,4,-3,0,-4,2,4,-3,0,-4

Dann kehren wir die Liste um:

 <original->
 -4,0,-3,4,2, -4,0,-3, 4........
           <-2's block->     

Als nächstes erhalten wir für jedes Element entsprechende Blöcke von [len(x)+~i:][:n]. Das Slice wird umgekehrt sein, dh 2 wird einen Block erhalten: [2,-4,0,-3,4]Dies ist umgekehrt zu den erwarteten [4,-3,0,-4,2], aber wir brauchen schließlich die Summe. Das funktioniert also. :)


Nicht sicher, warum Sie zuerst umkehren müssen? Können Sie die Slices später nicht in umgekehrter Richtung ändern?
Mr. Xcoder

@ Mr.Xcoder Ich denke, es gibt einen Weg, aber dieser Weg war weniger langweilig, also blieb ich bei diesem ...: D
officialaimm

1
Ich denke x[-n+1:]+x*n, Sie sollten die Liste mit ausreichender Polsterung auf beiden Seiten geben, ohne ( lambda x,n:[sum((x[-n+1:]+x*n)[i:i+n])for i in range(len(x))]) umkehren zu müssen
muru

1
@muru Hast du es gerade bearbeitet? Jetzt gehts. Vielen Dank!
offiziell


1

K (oK) , 18 Bytes

Lösung:

{+/+y':(1-y+#x)#x}

Probieren Sie es online!

Beispiele:

{+/+y':(1-y+#x)#x}[1 2;5]
7 8
{+/+y':(1-y+#x)#x}[-5 4 0 1 0 -10 -4;4]
-19 -15 -5 0 5 -9 -13
{+/+y':(1-y+#x)#x}[-10 0 10;4]
-10 0 10

Erläuterung:

Wollte gerade eine 31-Byte- Lösung veröffentlichen, dann fiel mir ein, dass in OK ein Schiebefenster eingebaut ist ...

{+/+y':(1-y+#x)#x} / the solution
{                } / lambda with implicit x and y parameters
               #x  / take (#) from list x
       (    #x)    / length of x
          y+       / add y (window size)
        1-         / subtract from 1 to give a negative
    y':            / sliding window of size y
   +               / flip
 +/                / sum

Bonus:

Die 31-Byte- Lösung, die auch in K4 funktioniert :

q)k){+/+x#y#'|+(:':\|(1-y+x:#x)#x)}[2 4 -3 0 -4;3]
-2 2 3 1 -7
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.