Tổng di chuyển


24

Lấy cảm hứng từ một câu hỏi tại Stack Overflow .

Cho một mảng số nguyên không trống xvà một số nguyên dương n, tính tổng của từng khối chiều dài trượtn dọc theo mảng x, điền tròn các giá trị còn thiếu ở bên trái với các giá trị từ bên phải như sau:

  • khối đầu tiên chứa mục đầu tiên của x, trước n-1các mục được dịch chuyển tròn;
  • khối thứ hai có các mục đầu tiên và thứ hai x, trước n-2các mục được dịch chuyển tròn; vân vân

Mảng đầu ra ycó cùng kích thước với x. Có thể nvượt quá độ dài xvà sau đó các giá trị xđược sử dụng lại nhiều lần .

Ví dụ

Ví dụ 1 (các giá trị chỉ được sử dụng lại một lần)

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

đưa ra như đầu ra

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

Ở đâu

  • -2là tổng của khối [0, -4, 2](hai giá trị đầu tiên đến từ sự dịch chuyển tròn)
  • 2là tổng của [-4, 2, 4](giá trị đầu tiên đến từ sự dịch chuyển tròn)
  • 3là tổng của [2, 4, -3](không cần dịch chuyển vòng tròn nữa)
  • 1 là tổng của [4, -3, 0]
  • -7là tổng của [-3, 0, -4].

Ví dụ 2 (các giá trị được sử dụng lại nhiều lần)

x = [1, 2]
n = 5

đưa cho

y = [7, 8]

Ở đâu

  • 7là tổng của khối [1, 2, 1, 2, 1](bốn giá trị đầu tiên đã được sử dụng lại theo vòng tròn)
  • 8là tổng của khối [2, 1, 2, 1, 2](ba giá trị đầu tiên đã được sử dụng lại theo vòng tròn)

Quy tắc bổ sung

  • Thuật toán sẽ làm việc cho các mảng có kích thước tùy ý và cho các giá trị nguyên tùy ý. Có thể chấp nhận nếu chương trình bị giới hạn bởi loại dữ liệu hoặc giới hạn bộ nhớ; nhưng các giá trị nguyên dương cũng như âm phải được xử lý.
  • Đầu vào / đầu ra có thể được lấy / sản xuất bằng bất kỳ phương tiện hợp lý nào .
  • Các chương trình hoặc chức năng được cho phép, trong bất kỳ ngôn ngữ lập trình . Sơ hở tiêu chuẩn bị cấm.
  • Mã ngắn nhất trong byte thắng.

Các trường hợp thử nghiệm

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, tại sao bạn phải sử dụng các mục trước?
Neil

Câu trả lời:


3

Thạch , 5 byte

ṙC€}S

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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

3 byte được lưu nhờ vào @Luis!

:gyn&Z+

Đầu vào đầu tiên là kích thước của cửa sổ và đầu vào thứ hai là mảng

Dùng thử tại MATL Online

Giải trình

       % 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

Toán học, 29 byte

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

Hoặc cùng chiều dài:

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

6

CJam (16 byte)

{_2$*ew1fb\,~)>}

Bộ kiểm tra trực tuyến . Đây là một khối ẩn danh (hàm) lấy mảng và độ dài trên ngăn xếp và để lại một mảng trên ngăn xếp.

Mổ xẻ

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

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

Hãy thử trực tuyến!

Chỉ cần một số vòng lặp chỉ mục và truy cập danh sách đầu vào tại các chỉ số modulo độ dài của danh sách.


3

Haskell , 69 65 64 byte

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

Hãy thử trực tuyến! Ví dụ sử dụng : [2, 4, -3, 0, -4] # 3.


Sử dụng n thành công thay vì các mục trước có thể là 50 46 byte (loại bỏ ngược lại ở đầu và cuối):

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

Hãy thử trực tuyến!



2

Bình thường , 18 16 byte

Đã lưu 2 byte nhờ @FryAmTheEggman !

JEms<.>*JQ-JhdJl

Hãy thử ở đây hoặc Xác minh tất cả các trường hợp thử nghiệm.

Đã sửa tất cả các lỗi với chi phí -6 byte ! Cảm ơn Luis rất nhiều vì đã khiến tôi hiểu nhiệm vụ trong trò chuyện.


Giải thích (sẽ được cập nhật)

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.

Có thể là một cách tốt hơn trước khi đảo ngược, cố gắng chơi golf sớm.
Ông Xcoder

16 byte nhưng tôi cảm thấy như vẫn còn một cái gì đó ngắn hơn.
FryAmTheEggman

@FryAmTheEggman Cảm ơn. Tôi cảm thấy nó nên ngắn hơn nhưng tôi không thể tìm ra cách
Ông Xcoder

2

Java 8, 102 byte

Lambda (cà ri) từ int[]đến lambda từ Integerđến int[]. Chỉ định cho 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;}

Dùng thử trực tuyến

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) % ltính phần còn lại không âm cho bất kỳ j. Lấy từ đây .



2

Octave, 53 byte

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

Hãy thử trực tuyến!

  • Các imfilterchức năng với tùy chọn circulartính chập tròn ở trung tâm của cửa sổ để kết quả nên được thay đổi.


2

Perl 6 , 42 39 byte

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

Hãy thử trực tuyến!

Mục nhập Perl 6 đầu tiên của tôi. Có lẽ có thể được cải thiện.


Lưu ý rằng đôi khi bạn có thể giảm độ dài bằng cách sử dụng một khối nhọn với các biến không rõ ràng thay vì một khối có tham số giữ chỗ ->\a,\b{[«+»] map {a.rotate(-$_)},^b}Lưu ý rằng nó không có trong trường hợp này nhưng sẽ có nếu có một phiên bản khác của $bmã.
Brad Gilbert b2gills

2

Kotlin , 141 140 138 byte

Chỉ là lần đầu tiên đi

Nộp hồ sơ

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

Làm đẹp

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

Dùng thử

Chỉnh sửa

  • Đã xóa dòng mới trước khung đóng cuối cùng

1

Röda , 52 byte

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

Hãy thử trực tuyến!

Giải trình:

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 byte

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

Lưu 2 byte nhờ Neil

Sử dụng:

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
Các ,Nngoại hình không cần thiết đối với tôi ...
Neil

@Neil Bạn nói đúng, cảm ơn
Bálint


1

Python 2 , 69 61 byte

- 8 byte Cảm ơn rất nhiều @muru

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

Hãy thử trực tuyến!

Giải trình:

Đầu tiên chúng ta cần đảm bảo có đủ số ở bên trái của danh sách ban đầu, điều này được thực hiện bởi x*n+xmột phần.

Ví dụ [2,4,-3,0,4],5:

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

Sau đó, chúng tôi sẽ đảo ngược danh sách:

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

Tiếp theo, chúng tôi thu được các khối tương ứng cho mỗi phần tử bằng cách [len(x)+~i:][:n]. Lát cắt sẽ ngược lại, tức là 2 sẽ đạt được một khối: [2,-4,0,-3,4]ngược lại với dự kiến [4,-3,0,-4,2], nhưng sau tất cả chúng ta cần tổng. Vì vậy, điều này hoạt động. :)


Không chắc chắn tại sao bạn phải đảo ngược đầu tiên? Bạn không thể sửa đổi các lát sau này theo hướng ngược lại chứ?
Ông Xcoder

@ Mr.Xcoder Tôi nghĩ rằng có một cách nhưng cách này ít tẻ nhạt vì vậy tôi dán với điều này ...: D
officialaimm

1
Tôi nghĩ x[-n+1:]+x*nnên cung cấp cho bạn danh sách với đủ phần đệm ở hai bên, mà không phải đảo ngược ( lambda x,n:[sum((x[-n+1:]+x*n)[i:i+n])for i in range(len(x))])
muru

1
@muru Bạn vừa chỉnh sửa nó? Bây giờ, nó hoạt động. Cảm ơn rất nhiều!
chính thức


1

K (oK) , 18 byte

Dung dịch:

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

Hãy thử trực tuyến!

Ví dụ:

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

Giải trình:

Đã chuẩn bị đăng một giải pháp 31 byte thì tôi nhớ rằng oK có tích hợp sẵn cho các cửa sổ trượt ...

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

Tiền thưởng:

Các 31 byte giải pháp mà cũng làm việc trong K4 :

q)k){+/+x#y#'|+(:':\|(1-y+x:#x)#x)}[2 4 -3 0 -4;3]
-2 2 3 1 -7
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.