Tính tổng tích lũy giới hạn của một vectơ


19

Tổng tích lũy của một vectơ được tính bằng cách đơn giản lấy tổng của tất cả các phần tử trước đó. Ví dụ:

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]

Bây giờ, áp đặt giới hạn trên và giới hạn dưới, nghĩa là bạn ngừng tăng tổng tích lũy nếu nó ở giới hạn trên và ngừng giảm tổng tích lũy nếu ở giới hạn dưới. Một ví dụ đơn giản:

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]

Vectơ đầu vào bao gồm các số nguyên, không nhất thiết chỉ 1-1, cả dương và âm. Giả sử rằng upper_lim >= lower_lim. Nếu phần tử đầu tiên của vectơ nằm ngoài ranh giới, hãy nhảy trực tiếp đến ranh giới (xem ví dụ cuối).

Viết hàm lấy một vectơ số nguyên làm đầu vào và hai số nguyên biểu thị giới hạn trên và dưới. Xuất ra vectơ tích lũy giới hạn, như được định nghĩa ở trên. Đầu vào có thể là đối số chức năng hoặc từ STDIN.

Quy tắc golf tiêu chuẩn áp dụng.

Ví dụ:

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.

Câu trả lời:


5

Bình thường, 14 byte

t.u@S+Q+NY1vwZ

Dùng thử trực tuyến: Trình diễn hoặc Test Suite

Giải trình

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

Camam 16 15 byte

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

Dùng thử trực tuyến

Cái này lấy danh sách làm đối số thứ nhất và cặp giới hạn trên / dưới làm danh sách 2 phần tử thứ hai. Ví dụ đầu vào:

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

Phiên bản mới nhất tiết kiệm 1 byte bằng cách sắp xếp 3 giá trị và lấy giá trị trung bình, thay vì sử dụng thao tác tối đa và tối thiểu. Điều này cũng được sử dụng trong giải pháp của Jakube, cũng như được đề xuất bởi Martin.

Giải trình:

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 byte

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

Xác định một hàm ẩn danh nhận đầu vào ở định dạng lower bound, upper bound, vector (as JS Array). Tôi không biết nó có thể ngắn hơn được không, nhưng tôi sẽ thử. Gợi ý chào mừng!


4

Haskell, 37 byte

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

Ví dụ sử dụng: 6 # (-2) $ [1,4,3,-10,3,2,2,5,-4]-> [1,5,6,-2,1,3,5,6,2].

Bắt đầu tổng với 0để sửa các giá trị ban đầu ngoài giới hạn. Lấy tailđể loại bỏ nó từ kết quả cuối cùng.


3

R, 61 byte

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

sapplylà hàm để áp dụng một hàm cho mọi phần tử của vectơ (ở đây x) nhưng nó thường được thực hiện trong bối cảnh mà tất cả các đánh giá là độc lập và không có tác dụng phụ. Tuy nhiên, ở đây, tôi sử dụng <<-toán tử để thực hiện một phép gán trong môi trường cha / cuộc gọi sapplyđể tổng số tích lũy scó thể được lưu trữ bên ngoài các đánh giá lặp. Đây là một thực tế rất tệ ...


3

Toán học, 46 byte

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

Nhân vật hài hước là U + F4A1 cho \[Function]. Nếu phần tử đầu tiên có thể được coi là nằm trong phạm vi, tôi có thể lưu 7 byte.


3

Julia, 44 42 38 byte

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

Điều này tạo ra một hàm fchấp nhận một mảng và hai số nguyên và trả về một mảng.

Ung dung:

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

Đã lưu 2 byte bằng cách sử dụng ý tưởng của ETHproductions bao gồm tổng tích lũy làm tham số hàm và 1 byte nhờ Glen O.


3

Python 2, 67 byte

lambda u,l,v:reduce(lambda x,y:x+[max(min(x[-1]+y,u),l)],v,[0])[1:]

2

Chồn 0,9 , 30 byte

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

Điều này, như là một hàm, giả sử ngăn xếp đã được khởi tạo trước high, low, vector. Chương trình đầy đủ bên dưới ( 37 byte ) và lấy đầu vào là high, low, vector.

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

Hãy thử nó ở đây.

Giải trình

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

Nó dài, nhưng nó hoạt động

#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"]");}

Ví dụ sử dụng

#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);
}

Đầu ra sẽ là

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

1

APL, 29 27 18 byte

Như Dennis đã chỉ ra trong trò chuyện, \(mở rộng) hoạt động từ trái sang phải, nhưng áp dụng chức năng được mở rộng với từ phải sang trái. Vì vậy, chúng ta không thể làm 1↓(⎕⌈⎕⌊+)\0,⎕. Chúng tôi ,\xử lý vấn đề này bằng cách lấy mảng, và sau đó xử lý từng phân đoạn riêng biệt bằng cách sử dụng /(gấp).

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

Đầu vào theo thứ tự array, upper bound, lower bound.

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.