원형 이동 합계


24

Stack Overflow 의 질문 에서 영감을 얻었습니다 .

정수 비어 배열 감안 x하고 양수 n, 컴퓨팅 합계 각각의 슬라이딩 블록 의 길이를 n배열을 따라 x, 다음 오른쪽 값을 왼쪽에서 누락 값을 충전 :

  • 첫 번째 블록은의 첫 번째 항목을 포함하며 그 x앞에는 n-1순환 이동 된 항목이 있습니다.
  • 제 2 블록은 원형으로 시프트 된 엔트리에 x선행하는 제 1 및 제 2 엔트리를 n-2가지며; 등등.

출력 배열 y의 크기는 x입니다. 것은 가능 n의 길이를 초과 x하고 값이 x원형으로되어 재사용 수회 .

예 1 (값은 한 번만 재 사용됨)

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

출력으로 주다

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

어디에

  • -2블록의 합입니다 [0, -4, 2](처음 두 값은 원형 이동에서 나옵니다)
  • 2의 합입니다 [-4, 2, 4](첫 번째 값은 원형 이동에서 나옵니다)
  • 3[2, 4, -3](더 이상 원형 이동이 필요하지 않음 )의 합입니다.
  • 1 ~의 합이다 [4, -3, 0]
  • -7의 합입니다 [-3, 0, -4].

예 2 (값이 여러 번 재 사용됨)

x = [1, 2]
n = 5

주기

y = [7, 8]

어디에

  • 7블록의 합입니다 [1, 2, 1, 2, 1](처음 4 개의 값이 순환 재 사용됨)
  • 8블록의 합입니다 [2, 1, 2, 1, 2](처음 세 값은 순환 재 사용됨)

추가 규칙

  • 이 알고리즘은 임의의 크기의 배열과 임의의 정수 값에 대해 작동해야합니다. 프로그램이 데이터 유형 또는 메모리 제한에 의해 제한되는 경우 허용됩니다. 그러나 양의 정수 값뿐만 아니라 양수도 처리해야합니다.
  • 합리적인 수단으로 입 / 출력을 취하거나 생산할 수 있습니다 .
  • 모든 프로그래밍 언어의 프로그램 또는 기능 이 허용 됩니다 . 표준 허점 은 금지되어 있습니다.
  • 바이트 단위의 최단 코드가 이깁니다.

테스트 사례

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, 왜 이전 항목을 사용해야 했습니까?
Neil

답변:


3

젤리 , 5 바이트

ṙC€}S

온라인으로 사용해보십시오!

작동 원리

ṙ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 바이트

@Luis 덕분에 3 바이트를 절약했습니다!

:gyn&Z+

첫 번째 입력은 창의 크기이고 두 번째 입력은 배열입니다

MATL Online 에서 사용해보십시오

설명

       % 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

매스 매 티카, 29 바이트

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

또는 같은 길이 :

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

6

CJam (16 바이트)

{_2$*ew1fb\,~)>}

온라인 테스트 스위트 . 이것은 익명 블록 (함수)이며 스택에서 배열과 길이를 가져 와서 스택에 배열을 남깁니다.

해부

{       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

하스켈, 57 바이트

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

온라인으로 사용해보십시오!

인덱스에서 입력 인덱스를 루핑하고 액세스하는 인덱스 중 일부는 목록의 길이를 모듈로합니다.




2

Pyth , 18 16 바이트

@FryAmTheEggman 덕분에 2 바이트가 절약되었습니다 !

JEms<.>*JQ-JhdJl

여기에서 시도 하거나 모든 테스트 사례를 확인하십시오.

-6 바이트 의 비용으로 모든 결함을 수정했습니다 ! 채팅 작업을 이해하게 해준 Luis에게 감사합니다.


설명 (업데이트 됨)

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.

리버 싱하기 전에 더 나은 방법이 될 수 있으며 곧 골프를 치려고합니다.
Mr. Xcoder

있어 16 바이트를 여전히 짧은 뭔가가 있어야 같은 느낌.
FryAmTheEggman

@FryAmTheEggman 감사합니다. 나는 그것이 더 짧아야한다고 생각하지만 어떻게 알아낼 수 없습니다
Mr. Xcoder

2

자바 8, 102 바이트

람다에서 (카레) int[]로부터 람다 Integerint[]. 에 할당하십시오 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;}

온라인으로 사용해보십시오

언 골프 람다

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) % lany의 음이 아닌 나머지를 계산합니다 j. 여기 에서 찍은 .



2

옥타브, 53 바이트

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

온라인으로 사용해보십시오!

  • imfilter옵션 이있는 함수 circular는 창 중심에서 원형 컨벌루션을 계산하므로 결과를 이동해야합니다.


2

펄 6 , 42 39 바이트

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

온라인으로 사용해보십시오!

나의 첫번째 Perl 6 항목. 아마 향상 될 수 있습니다.


자리 표시 자 매개 변수가있는 블록이 아닌 sigilless 변수가있는 뾰족한 블록을 사용하여 길이를 줄일 수도 있습니다. ->\a,\b{[«+»] map {a.rotate(-$_)},^b}이 경우 $b에는 코드 에 다른 인스턴스가 있는 경우가 아니라는 점에 유의하십시오 .
브래드 길버트 b2gills

2

코 틀린 , 141 (140) 138 바이트

첫 번째 이동

제출

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

미화

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

편집

  • 마지막 닫는 대괄호 앞에있는 줄 바꿈을 제거했습니다.

1

로다 , 52 바이트

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

온라인으로 사용해보십시오!

설명:

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

자바 스크립트 ES6 80 78 바이트

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 덕분에 2 바이트 절약

용법:

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
,N나에게 불필요한 외모 ...

@Neil 당신이 맞아요, 감사합니다
Bálint


1

파이썬 2 , 69 61 바이트

-8 바이트 감사합니다 @muru

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

온라인으로 사용해보십시오!

설명:

먼저 원래 목록의 왼쪽에 충분한 숫자가 있는지 확인해야합니다. x*n+x 부품에 .

예를 들면 [2,4,-3,0,4],5:

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

그런 다음 목록을 뒤집습니다.

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

다음으로 각 요소에 해당하는 블록을 얻습니다 [len(x)+~i:][:n]. 슬라이스는 반전됩니다. 즉 2는 블록을 얻습니다. [2,-4,0,-3,4]예상 [4,-3,0,-4,2]과 반대 이지만 결국 합계가 필요합니다. 그래서 이것은 작동합니다. :)


왜 먼저 뒤집어 야하는지 잘 모르십니까? 나중에 반대 방향으로 슬라이스를 수정할 수 없습니까?
Mr. Xcoder

@ Mr.Xcoder 방법이 있다고 생각하지만이 방법은 덜 지루했기 때문에 이것을 고수했습니다 ... : D
officialaimm

1
나는 x[-n+1:]+x*n당신에게 ( lambda x,n:[sum((x[-n+1:]+x*n)[i:i+n])for i in range(len(x))]) 을 되돌릴 필요없이 양쪽에 충분한 패딩을 가진 목록을 주어야 한다고 생각 합니다.
muru

1
@muru 방금 편집 했습니까? 이제 작동합니다. 고마워요!
officialaimm


1

K (oK) , 18 바이트

해결책:

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

온라인으로 사용해보십시오!

예 :

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

설명:

31 바이트 솔루션 을 게시하려고 했는데 oK 에 슬라이딩 윈도우 가 내장 되어 있다는 것을 기억했습니다 ...

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

보너스:

31 바이트 도 작동 솔루션 K4 :

q)k){+/+x#y#'|+(:':\|(1-y+x:#x)#x)}[2 4 -3 0 -4;3]
-2 2 3 1 -7
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.