คำนวณผลรวมสะสมของเวกเตอร์ที่มีขอบเขต


19

ผลรวมสะสมของเวกเตอร์คำนวณได้ง่ายๆโดยหาผลรวมขององค์ประกอบก่อนหน้าทั้งหมด ตัวอย่างเช่น

vec =     [1  1  1 -1 -1 -1 -1 -1  1  1  1  1 -1]
cum_vec = [1  2  3  2  1  0 -1 -2 -1  0  1  2  1]

ตอนนี้กำหนดขีด จำกัด บนและล่างหมายความว่าคุณหยุดเพิ่มผลรวมสะสมถ้ามันอยู่ที่ขีด จำกัด บนและหยุดลดผลรวมสะสมถ้ามันอยู่ที่ขีด จำกัด ล่าง ตัวอย่างง่ายๆ:

upper_lim = 2
lower_lim = -1
vec =     [1  1  1 -1 -1 -1 -1 -1  1  1  1  1 -1]
cum_vec = [1  2  2  1  0 -1 -1 -1  0  1  2  2  1]

เวกเตอร์อินพุตประกอบด้วยจำนวนเต็มไม่จำเป็นเท่านั้น1และ-1ทั้งบวกและลบ upper_lim >= lower_limสมมติว่า หากองค์ประกอบแรกของเวกเตอร์อยู่นอกขอบเขตให้ข้ามไปที่ขอบเขตโดยตรง (ดูตัวอย่างสุดท้าย)

เขียนฟังก์ชันที่ใช้เวกเตอร์ของจำนวนเต็มเป็นอินพุตและจำนวนเต็มสองจำนวนที่แทนขีด จำกัด บนและล่าง เอาท์พุทเวกเตอร์สะสมที่ถูกผูกไว้ตามที่กำหนดไว้ข้างต้น อินพุตอาจเป็นฟังก์ชันอาร์กิวเมนต์หรือจาก STDIN ก็ได้

บังคับใช้กฎกอล์ฟมาตรฐาน

ตัวอย่าง:

upper_lim = 6
lower_lim = -2
vec =     [1  4  3 -10  3  2  2  5 -4]
cum_vec = [1  5  6  -2  1  3  5  6  2]

upper_lim = 100
lower_lim = -100
vec =     [1  1  1  1  1  1]
cum_vec = [1  2  3  4  5  6]

upper_lim = 5
lower_lim = 0
vec =     [10 -4 -3  2]
cum_vec = [5   1  0  2]

upper_lim = 0
lower_lim = 0
vec =     [3  5 -2  1]
cum_vec = [0  0  0  0]

upper_lim = 10
lower_lim = 5
vec =     [1  4  6]
cum_vec = [5  9 10]
           |
           Note, jumped to 5, because 5 is the lower bound.

คำตอบ:


5

Pyth, 14 ไบต์

t.u@S+Q+NY1vwZ

ลองใช้ออนไลน์: การสาธิตหรือชุดทดสอบ

คำอธิบาย

t.u@S+Q+NY1vwZ  implicit: Q = first input list [upper_lim, lower_lim]
 .u        vwZ  for each number Y in the next input list, update N = 0 with:
       +NY         N + Y
     +Q            append this to Q
    S              sort this list
   @      1        take the middle element
                .u returns a list with all intermediate values of N
t                  remove the first value, print the rest

5

CJam, 16 15 ไบต์

l~f{\T++$1=:T}`

ลองออนไลน์

นี่ใช้รายการเป็นอาร์กิวเมนต์แรกและคู่ของขีด จำกัด บน / ล่างเป็นรายการ 2 องค์ประกอบที่สอง อินพุตตัวอย่าง:

[1 4 3 -10 3 2 2 5 -4] [6 -2]

เวอร์ชันล่าสุดบันทึก 1 ไบต์โดยการเรียงลำดับ 3 ค่าและรับค่ากลางแทนที่จะใช้การดำเนินการสูงสุดและต่ำสุด สิ่งนี้ยังใช้ในการแก้ปัญหาของจากุเบเช่นเดียวกับที่มาร์ตินแนะนำ

คำอธิบาย:

l~    Get and parse input. This leaves the value and bounds lists on the stack.
f{    Apply block with value (the bounds list).
  \     Swap new value to top.
  T     Get previous value from variable T (which is default initialized to 0).
  +     Add new value and previous value.
  +     Append new value to bounds list, producing a 3 value list.
  $     Sort it...
  1=    And take the middle value.
  :T    Store in variable T for next iteration.
}     End of apply loop.
`     Convert list to string.

4

JavaScript (ES6), 43 ไบต์

(l,u,v,p=0)=>v.map(c=>p=(p+=c)<l?l:p>u?u:p)

lower bound, upper bound, vector (as JS Array)กำหนดฟังก์ชั่นที่ไม่ระบุชื่อที่จะเข้าในรูปแบบ ฉันไม่รู้ว่ามันจะสั้นกว่านี้หรือไม่ แต่ฉันจะลอง ยินดีต้อนรับข้อเสนอแนะ!


4

Haskell, 37 ไบต์

u#l=tail.scanl(((min u.max l).).(+))0

ตัวอย่างการใช้งาน: ->6 # (-2) $ [1,4,3,-10,3,2,2,5,-4][1,5,6,-2,1,3,5,6,2]

เริ่มผลรวมด้วย0เพื่อแก้ไขค่าเริ่มต้นนอกขอบเขต ใช้tailเพื่อลบออกจากผลลัพธ์สุดท้าย


3

R, 61 ไบต์

function(x,l,u,s=0)sapply(x,function(i)s<<-min(u,max(l,s+i)))

sapplyเป็นฟังก์ชันที่ใช้ฟังก์ชันกับทุกองค์ประกอบของเวกเตอร์ (ที่นี่x) แต่มักจะทำในบริบทที่การประเมินทั้งหมดเป็นอิสระและไม่มีผลข้างเคียง อย่างไรก็ตามที่นี่ฉันใช้<<-โอเปอเรเตอร์เพื่อทำการกำหนดค่าในสภาพแวดล้อมพาเรนต์ / การโทรของsapplyเพื่อให้ผลรวมสะสมsสามารถเก็บไว้นอกการประเมินซ้ำได้ นี่เป็นวิธีปฏิบัติที่ไม่ดีมาก ...


3

Mathematica ขนาด 46 ไบต์

Rest@FoldList[{a,b}Min[a+b,#2]~Max~#3,0,#]&

ตัวละครที่ตลกคือ U + F4A1 \[Function]สำหรับ หากสามารถสันนิษฐานได้ว่าองค์ประกอบแรกอยู่ในช่วงฉันสามารถบันทึกได้ 7 ไบต์


3

Julia, 44 42 38 ไบต์

f(x,l,u,s=0)=[s=clamp(s+i,l,u)for i=x]

สิ่งนี้จะสร้างฟังก์ชั่นfที่ยอมรับอาร์เรย์และจำนวนเต็มสองจำนวนแล้วส่งกลับอาร์เรย์

Ungolfed:

function f(v::Array, u::Int, l::Int, s::Int = 0)
    # The parameter s is the cumulative sum, which begins
    # at 0

    # For each element i of v, define s to be s+i if
    # l ≤ s+i ≤ u, l if s+i < l, or u if s+i > u
    x = [s = clamp(s + i, l, u) for i = v]

    return x
end

บันทึก 2 ไบต์โดยใช้แนวคิดของ ETHproductions ในการรวมผลรวมสะสมเป็นพารามิเตอร์ฟังก์ชันและ 1 ไบต์ด้วย Glen O



2

Minkolang 0.9 , 30 ไบต์

0I3-[2g+d0c`,3&x0cd1c`3&x1cdN]

นี่เป็นฟังก์ชันสมมติว่าสแต็กได้ถูกเตรียมข้อมูลhigh, low, vectorเบื้องต้นไว้ล่วงหน้าแล้ว โปรแกรมเต็มรูปแบบอยู่ด้านล่าง ( 37 ไบต์ ) high, low, vectorและจะเข้าเป็น

(n$I$)0I4-[2g+d0c`,3&x0cd1c`3&x1cdN].

ลองที่นี่

คำอธิบาย

(n$I$)                                   Read in integers from input until empty
      0                                  Initialize cumulative sum
       I4-[                        ]     Loop over vector
           2g+                           Get the next partial sum
              d0c`,3&x0c                 If too high, replace with high
                        d1c`3&x1cd       If too low, replace with low
                                  N      Output as integer
                                    .    Stop

1

C 98 ไบต์

มันยาว แต่ใช้งานได้

#define P printf(
void c(*v,n,u,l,s,c){P"[");while(c++<n)s+=*v++,s=s<u?s>l?s:l:u,P"%d ",s);P"]");}

ตัวอย่างการใช้งาน

#define P printf(
void c(*v,n,u,l,s,c) {
    P"[");
    while(c++<n)
        s+=*v++,s=s<u?s>l?s:l:u,P"%d ",s);
    P"]");
}

int main() {
    int vec[9] = {1, 4, 3, -10, 3, 2, 2, 5, -4};
    int upper = 6, lower = -2, count = 9;
    c(vec, count, upper, lower, 0, 0);
}

ผลลัพธ์จะเป็น

[1 5 6 -2 1 3 5 6 2 ]

1

APL, 29 27 18 ไบต์

ดังที่เดนนิสชี้ในการแชท\(ขยาย) ทำงานจากซ้ายไปขวา แต่ใช้ฟังก์ชันที่ขยายด้วยจากขวาไปซ้าย 1↓(⎕⌈⎕⌊+)\0,⎕ดังนั้นเราจึงไม่สามารถเพียงแค่ทำ เราแก้ไขสิ่งนี้โดยการใช้,\อาเรย์แล้วประมวลผลแต่ละ subarray แยกกันโดยใช้/(fold)

1↓(⎕⌈⎕⌊+)/¨⌽¨,\0,⎕

array, upper bound, lower boundการป้อนข้อมูลในการสั่งซื้อ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.