ผลรวมการเคลื่อนที่แบบวงกลม


24

แรงบันดาลใจจากคำถามที่กองมากเกิน

กำหนดอาร์เรย์ที่ไม่ว่างเปล่าของจำนวนเต็มxและเป็นจำนวนเต็มบวกn, คำนวณผลรวมของแต่ละบล็อกเลื่อนความยาวnพร้อมอาร์เรย์x, circularlyกรอกค่าที่ขาดหายไปทางด้านซ้ายที่มีค่าจากขวาดังนี้

  • บล็อกแรกมีรายการแรกของxนำหน้าด้วยn-1รายการที่เปลี่ยนเป็นวงกลม
  • บล็อกที่สองมีรายการแรกและรายการที่สองของxนำหน้าด้วยn-2รายการที่เปลี่ยนเป็นวงกลม และอื่น ๆ

อาร์เรย์เอาต์พุตyมีขนาดเท่าxกันกับ มันเป็นไปได้สำหรับnที่จะเกินความยาวของxแล้วค่าของxกำลัง circularly นำกลับมาใช้หลายครั้ง

ตัวอย่าง

ตัวอย่างที่ 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](ค่าสี่ค่าแรกถูกนำกลับมาใช้แบบวนรอบ)
  • 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
เฮ้อทำไมคุณต้องใช้รายการก่อนหน้า?
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 ไบต์

บันทึก 3 ไบต์ด้วย @Luis!

: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

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

Haskell, 57 ไบต์

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

ลองออนไลน์!

เพียงบางดัชนีการวนลูปและการเข้าถึงรายการอินพุตที่ดัชนี modulo ความยาวของรายการ


3

Haskell , 69 65 64 ไบต์

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

ลองออนไลน์! ตัวอย่างการใช้: [2, 4, -3, 0, -4] # 3.


การใช้ที่n ประสบความสำเร็จแทนที่จะเป็นรายการก่อนหน้าอาจเป็น50 46 ไบต์ (การกำจัดสิ่งที่ตรงกันข้ามในตอนต้นและตอนท้าย):

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

ลองออนไลน์!



2

Pyth , 18 16 ไบต์

บันทึก 2 ไบต์ขอบคุณ@FryAmTheEggman !

JEms<.>*JQ-JhdJl

ลองที่นี่หรือตรวจสอบกรณีทดสอบทั้งหมด

แก้ไขข้อบกพร่องทั้งหมดที่ราคา-6 ไบต์ ! ขอบคุณมากสำหรับหลุยส์ที่ทำให้ฉันเข้าใจงานในการแชท


คำอธิบาย (ที่จะปรับปรุง)

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 ขอบคุณ ฉันรู้สึกว่าควรจะสั้นกว่านี้ แต่ฉันไม่สามารถหาวิธีได้
Mr. Xcoder

2

Java 8, 102 ไบต์

แลมบ์ดา (แกงกะหรี่) จากint[]การแลมบ์ดาจากไปInteger มอบหมายให้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) % ljคำนวณค่าลบที่เหลือสำหรับการใด ๆ ที่นำมาจากที่นี่



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

Kotlin , 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

การแก้ไข

  • ลบ newline on ก่อนวงเล็บปิดล่าสุด

1

Röda , 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]'))

บันทึก 2 ไบต์ขอบคุณ Neil

การใช้งาน:

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

Python 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
เป็นทางการ

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 คุณเพิ่งแก้ไขหรือไม่ ตอนนี้มันใช้งานได้ ขอบคุณมาก!
อย่างเป็นทางการ


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 มีbuilt-inสำหรับหน้าต่างบานเลื่อน ...

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