Dairesel hareketli toplam


24

Yığın Taşması'ndaki bir sorudan ilham alındı .

Tamsayılar boş olmayan bir dizi göz önüne alındığında xve pozitif bir tamsayıdır n, hesaplamak toplamı her bir kayar bloğun uzunluğunun ndizisi boyunca x, dairesel aşağıdaki gibi sağdan değerleri ile sol eksik değerleri doldurma:

  • ilk blok x, önce n-1dairesel olarak kaydırılmış girişlerden önce gelen ilk girişi içerir ;
  • ikinci blok x, önce n-2dairesel olarak kaydırılmış girişlerden oluşan birinci ve ikinci girişlere sahiptir ; ve bunun gibi.

Çıkış dizisi yile aynı boyutta x. nUzunluğunu aşmak mümkündür xve daha sonra değerleri birkaç kezx dairesel olarak yeniden kullanılır .

Örnekler

Örnek 1 (değerler yalnızca bir kez yeniden kullanılır)

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

çıktı olarak vermek

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

nerede

  • -2bloğun toplamıdır [0, -4, 2](ilk iki değer dairesel kaymadan gelir)
  • 2toplam [-4, 2, 4]değeridir (ilk değer dairesel kaymadan gelir)
  • 3toplamıdır [2, 4, -3](artık dairesel kaymaya gerek yok)
  • 1 toplamı [4, -3, 0]
  • -7toplamıdır [-3, 0, -4].

Örnek 2 (değerler birkaç kez yeniden kullanılır)

x = [1, 2]
n = 5

vermek

y = [7, 8]

nerede

  • 7bloğun toplamıdır [1, 2, 1, 2, 1](ilk dört değer dairesel olarak yeniden kullanılmıştır)
  • 8bloğun toplamıdır [2, 1, 2, 1, 2](ilk üç değer dairesel olarak yeniden kullanılmıştır)

Ek kurallar

  • Algoritma, keyfi büyüklükteki diziler ve isteğe bağlı tamsayı değerleri için çalışmalıdır. Programın veri tipi veya hafıza kısıtlamaları ile sınırlı olması kabul edilebilir; ancak pozitif ve negatif tamsayı değerleri de ele alınmalıdır.
  • Giriş / çıkış, herhangi bir makul yoldan alınabilir / üretilebilir .
  • Herhangi bir programlama dilinde programlara veya fonksiyonlara izin verilir . Standart boşluklar yasaktır.
  • Bayt cinsinden en kısa kod kazanır.

Test durumları

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, neden önceki girişleri kullanmak zorunda kaldın?
Neil

Yanıtlar:


3

Jöle , 5 bayt

ṙC€}S

Çevrimiçi deneyin!

Nasıl çalışır

ṙ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 bayt

@Luis sayesinde 3 bayt kaydedildi!

:gyn&Z+

İlk giriş pencerenin boyutudur ve ikinci giriş dizidir

MATL Online'da deneyin

açıklama

       % 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 bayt

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

Veya aynı uzunluk:

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

6

CJam (16 bayt)

{_2$*ew1fb\,~)>}

Çevrimiçi test paketi . Bu, diziyi ve istifin uzunluğunu alan ve istifin üzerine bir dizi bırakan isimsiz bir bloktur (fonksiyon).

teşrih

{       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 bayt

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

Çevrimiçi deneyin!

Sadece bazı indeks döngüleri ve giriş listesine erişerek indeksler listenin uzunluğu modulo.


3

Haskell , 69 65 64 bayt

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

Çevrimiçi deneyin! Örnek kullanımı: [2, 4, -3, 0, -4] # 3.


Kullanılması n başarılı yerine önceki olabilecek girişler 50 46 bayt (başında ve sonunda ters kurtulmak):

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

Çevrimiçi deneyin!



2

Pyth , 18 16 bayt

@FryAmTheEggman sayesinde 2 bayt kaydedildi !

JEms<.>*JQ-JhdJl

Burada deneyin veya tüm test durumlarını doğrulayın.

-6 bayt pahasına tüm kusurları düzeltildi ! Sohbetteki görevi anlamamı sağladığı için Luis'e çok teşekkür ederim.


Açıklama (güncellenecek)

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.

Yakında golf oynamaya çalışmak için geri gitmeden önce daha iyi bir yol olabilir.
Bay Xcoder

Got 16 bayt ama yine kısa bir şey olması gerekir gibi hissediyorum.
FryAmTheEggman

@FryAmTheEggman Teşekkürler. Daha kısa olması gerektiğini düşünüyorum ama nasıl yapılacağını
çözemiyorum

2

Java 8, 102 bayt

Lambda (curried) int[]gelen lambda Integeriçin int[]. Atama 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;}

Çevrimiçi Deneyin

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) % lHerhangi biri için negatif olmayan bir kalanı hesaplar j. Buradan alındı .



2

Octave, 53 bayt

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

Çevrimiçi deneyin!

  • imfilterSeçeneği ile fonksiyon circularsonucu kaymış olmalıdır böylece pencerenin ortasına yuvarlak konvolüsyonunu hesaplar.

2

05AB1E , 10 bayt

.׌ùOR¹g£R

Çevrimiçi deneyin!

açıklama

.×           # 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 bayt

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

Çevrimiçi deneyin!

Benim ilk Perl 6 girişi. Muhtemelen geliştirilebilir.


Uzunluğu, yer tutucu parametreli bir bloktan ziyade sigilless değişkenleri olan bir sivri blok kullanarak azaltabileceğinizi ->\a,\b{[«+»] map {a.rotate(-$_)},^b}unutmayın. Bu durumda olmadığını, ancak $bkodun başka bir örneğini olsaydı yapacağını unutmayın .
Brad Gilbert,

2

Kotlin , 141 140 138 bayt

Sadece ilk sefer

boyun eğme

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

Beautified

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

Düzenlemeler

  • Son kapatma braketinden önceki yeni satır kaldırıldı

1

Röda , 52 bayt

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

Çevrimiçi deneyin!

Açıklama:

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 bayt

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

Neil sayesinde 2 bayt kurtarıldı

Kullanımı:

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
,NBana gereksiz görünüyor ...
Neil

@Neil Haklısın, teşekkürler
Bálint


1

Python 2 , 69 61 bayt

- 8 bytes Çok teşekkürler

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

Çevrimiçi deneyin!

Açıklama:

Öncelikle, orijinal listenin solunda yeterli sayıda sayı olduğundan emin olmamız gerekir, bu x*n+xkısım tarafından elde edilir .

Örneğin [2,4,-3,0,4],5:

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

O zaman listeyi tersine çeviririz:

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

Daha sonra her eleman için karşılık gelen blokları elde ettik [len(x)+~i:][:n]. Dilim tersine dönecektir, yani 2 bir blok kazanacaktır: [2,-4,0,-3,4]bu beklenenlerin tersidir [4,-3,0,-4,2], ama sonuçta toplamına ihtiyacımız var. Yani bu işe yarıyor. :)


İlk önce neden geri döndüğünden emin değil misin? Dilimleri daha sonra ters yönde değiştiremez misiniz?
Bay Xcoder

@ Mr.Xcoder Bir yol olduğunu düşünüyorum ama bu yol daha az sıkıcıydı, bu yüzden buna bağlı kaldım ...: D
officialaimm

1
Sanırım x[-n+1:]+x*nsize her iki tarafta da yeterli lambda x,n:[sum((x[-n+1:]+x*n)[i:i+n])for i in range(len(x))]
dolgulu bir liste vermeliyim

1
@muru: Düzenledin mi? Şimdi çalışıyor. Çok teşekkürler!
officialaimm


1

K (oK) , 18 bayt

Çözüm:

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

Çevrimiçi deneyin!

Örnekler:

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

Açıklama:

31 baytlık bir çözüm göndermek üzereydi, o zaman OK’nin sürgülü pencereler için yerleşik olduğunu hatırladım .

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

31 bayt de çalışır çözüm K4 :

q)k){+/+x#y#'|+(:':\|(1-y+x:#x)#x)}[2 4 -3 0 -4;3]
-2 2 3 1 -7
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.