Hitung jumlah kumulatif vektor yang dibatasi

19

Jumlah kumulatif vektor dihitung dengan hanya mengambil jumlah semua elemen sebelumnya. Contohnya:

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]

Sekarang, tetapkan batas atas dan bawah, artinya Anda berhenti menambah jumlah kumulatif jika berada di batas atas, dan berhenti mengurangi jumlah kumulatif jika berada di batas bawah. Contoh sederhana:

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]

Vektor input terdiri dari bilangan bulat, tidak harus hanya 1dan -1, baik positif maupun negatif. Asumsikan itu upper_lim >= lower_lim. Jika elemen pertama vektor berada di luar batas, lompat langsung ke batas (lihat contoh terakhir).

Tulis fungsi yang mengambil vektor bilangan bulat sebagai input, dan dua bilangan bulat yang mewakili batas atas dan bawah. Keluarkan vektor kumulatif terbatas, seperti yang didefinisikan di atas. Input dapat berupa argumen fungsi atau dari STDIN.

Aturan golf kode standar berlaku.

Contoh:

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.
Stewie Griffin
sumber

Jawaban:

5

Pyth, 14 byte

t.u@S+Q+NY1vwZ

Cobalah online: Demonstrasi atau Test Suite

Penjelasan

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
Jakube
sumber
5

CJam, 16 15 byte

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

Cobalah online

Ini mengambil daftar sebagai argumen pertama, dan pasangan batas atas / bawah sebagai daftar 2-elemen kedua. Contoh input:

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

Versi terbaru menyimpan 1 byte dengan mengurutkan 3 nilai, dan mengambil nilai tengah, alih-alih menggunakan operasi max dan min. Ini juga digunakan dalam solusi Jakube, serta disarankan oleh Martin.

Penjelasan:

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.
Reto Koradi
sumber
4

JavaScript (ES6), 43 byte

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

Menentukan fungsi anonim yang mengambil input dalam format lower bound, upper bound, vector (as JS Array). Saya tidak tahu apakah bisa lebih pendek, tapi saya akan coba. Saran diterima!

Produksi ETH
sumber
4

Haskell, 37 byte

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

Contoh penggunaan: 6 # (-2) $ [1,4,3,-10,3,2,2,5,-4]-> [1,5,6,-2,1,3,5,6,2].

Mulai penjumlahan dengan 0untuk memperbaiki nilai awal di luar batas. Ambil tailuntuk menghapusnya dari hasil akhir.

nimi
sumber
3

R, 61 byte

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

sapplyadalah fungsi untuk menerapkan fungsi ke setiap elemen vektor (di sini x) tetapi biasanya dilakukan dalam konteks di mana semua evaluasi independen dan tanpa efek samping. Namun, di sini, saya menggunakan <<-operator untuk membuat penugasan di lingkungan induk / panggilan sapplysehingga jumlah kumulatif sdapat disimpan di luar evaluasi berulang. Ini adalah praktik yang sangat buruk ...

flodel
sumber
3

Mathematica, 46 byte

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

Karakter lucu adalah U + F4A1 untuk \[Function]. Jika elemen pertama dapat diasumsikan berada dalam jangkauan, saya bisa menghemat 7 byte.

LegionMammal978
sumber
3

Julia, 44 42 38 byte

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

Ini menciptakan fungsi fyang menerima array dan dua integer dan mengembalikan array.

Tidak Disatukan:

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

Disimpan 2 byte dengan menggunakan ide ETHproduk termasuk memasukkan jumlah kumulatif sebagai parameter fungsi dan 1 byte berkat Glen O.

Alex A.
sumber
3

Python 2, 67 Bytes

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

Minkolang 0,9 , 30 byte

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

Ini, sebagai fungsi, mengasumsikan stack telah diinisialisasi sebelumnya ke high, low, vector. Program lengkapnya ada di bawah ( 37 byte ) dan menerima input sebagai high, low, vector.

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

Coba di sini.

Penjelasan

(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
El'endia Starman
sumber
1

C 98 byte

Ini panjang, tetapi berhasil

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

Contoh penggunaan

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

Outputnya adalah

[1 5 6 -2 1 3 5 6 2 ]
Chris Loonam
sumber
1

APL, 29 27 18 byte

Seperti yang ditunjukkan Dennis dalam obrolan, \(perluas) berfungsi dari kiri ke kanan, tetapi terapkan fungsi yang diperluas dengan dari kanan ke kiri. Jadi kita tidak bisa begitu saja 1↓(⎕⌈⎕⌊+)\0,⎕. Kami mengatasinya dengan mengambil ,\array, dan kemudian memproses setiap subarray secara terpisah menggunakan /(lipat).

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

Masukan dalam urutan array, upper bound, lower bound.

lirtosiast
sumber