循環移動合計


24

Stack Overflowの質問に触発されまし

空ではない整数の配列xと正の整数nを指定すると、配列に沿った長さの各スライドブロックの合計を計算し、次のように左の欠損値を右からの値で循環充填します。nx

  • 最初のブロックには、循環シフトエントリxが先行するの最初のエントリが含まれn-1ます。
  • 2番目のブロックには、の最初と2番目のエントリがありx、その前にn-2循環シフトエントリがあります。等々。

出力配列のyサイズはと同じxです。nの長さを超えることは可能xで、その後、の値xは循環的に数回再利用されます。

例1(値は1回だけ再利用されます)

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

出力として与える

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

どこで

  • -2ブロックの合計です[0, -4, 2](最初の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](最初の3つの値は循環的に再利用されています)

追加のルール

  • このアルゴリズムは、任意のサイズの配列および任意の整数値に対して機能するはずです。プログラムがデータ型またはメモリ制限によって制限されている場合は許容できます。ただし、正の整数値と負の整数値を処理する必要があります。
  • 入力/出力は、任意の合理的な手段で取得/生成できます。
  • すべてのプログラミング言語プログラムまたは機能を使用できます標準的な抜け穴は禁止されています。
  • バイト単位の最短コードが優先されます。

テストケース

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
なぜ、前のエントリを使用する必要があったのですか?
ニール

回答:


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+

最初の入力はウィンドウのサイズで、2番目の入力は配列です

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

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
}




2

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

すぐにゴルフをしようとして、逆転する前に良い方法かもしれません。
ミスターXcoder

手に入れた16のバイトをまだ短く、何かがあるはずような気がします。
FryAmTheEggman

@FryAmTheEggmanありがとう。私はそれがより短くあるべき感じるが、私はどのように把握することはできません
氏Xcoder

2

Java 8、102バイト

ラムダ(カレー)from int[]to lambda from Integerto int[]。に割り当て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

Perl 6の42の 39バイト

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

オンラインでお試しください!

私の最初のPerl 6エントリー。おそらく改善できます。


あなたは時々 sigilless変数ではなく、プレースホルダパラメータを持つブロックと先のとがったブロックを使用して長さを短くすることもできますが->\a,\b{[«+»] map {a.rotate(-$_)},^b}、それはこのケースではないことに注意してくださいが、それは別のインスタンスがあった場合は希望$bのコードでは。
ブラッドギルバートb2gills

2

Kotlin141の 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

JavaScript 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私には不要なルックス...
ニール

@ニールあなたは正しい、ありがとう
バリント


1

パイソン269の 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]結局は合計が必要です。だから、これは動作します。:)


なぜ最初に逆転しなければならないのか分かりませんか?代わりにスライスを後で逆方向に変更することはできませんか?
ミスター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.