Tổng tích lũy phân vùng 2D


16

Thử thách

Cho ma trận Mr hàng và cột c và hai danh sách Boolean V có độ dài rH có chiều dài c , tính tổng tích lũy dọc và ngang tích lũy.

Quy tắc

  • rc lớn hơn hoặc bằng một

  • HV bắt đầu bằng một giá trị thực

  • Các giá trị trong M nằm trong miền số hợp lý của ngôn ngữ của bạn.

  • Phân vùng và tổng kết bắt đầu ở góc trên cùng bên trái.

Đi qua

Cho M :

┌──────────────┐
│ 1  2  3  4  5│
│ 6  7  8  9 10│
│11 12 13 14 15│
│16 17 18 19 20│
└──────────────┘

H :1 0 1 0 0

V :1 1 0 1

Tách M thành các nhóm cột, bắt đầu một nhóm mới ở mọi giá trị thực của H

┌─────┬────────┐
│ 1  2│ 3  4  5│
│ 6  7│ 8  9 10│
│11 12│13 14 15│
│16 17│18 19 20│
└─────┴────────┘

Tách từng nhóm cột thành các nhóm hàng, bắt đầu một nhóm mới ở mọi giá trị thực của V :

┌─────┬────────┐
│ 1  2│ 3  4  5│
├─────┼────────┤
│ 6  7│ 8  9 10│
│11 12│13 14 15│
├─────┼────────┤
│16 17│18 19 20│
└─────┴────────┘

Tổng cộng từng ô theo chiều ngang:

┌─────┬────────┐
│ 1  3│ 3  7 12│
├─────┼────────┤
│ 6 13│ 8 17 27│
│11 23│13 27 42│
├─────┼────────┤
│16 33│18 37 57│
└─────┴────────┘

Tổng cộng từng ô theo chiều dọc:

┌─────┬────────┐
│ 1  3│ 3  7 12│
├─────┼────────┤
│ 6 13│ 8 17 27│
│17 36│21 44 69│
├─────┼────────┤
│16 33│18 37 57│
└─────┴────────┘

Kết quả:

┌──────────────┐
│ 1  3  3  7 12│
│ 6 13  8 17 27│
│17 36 21 44 69│
│16 33 18 37 57│
└──────────────┘

Các trường hợp kiểm tra bổ sung

M :

┌───────────┐
│15 11 11 17│
│13 20 18  8│
└───────────┘

H : 1 0 0 1V :1 0

Kết quả:

┌───────────┐
│15 26 37 17│
│28 59 88 25│
└───────────┘

M :

┌─┐
│7│
└─┘

Kết quả ( HV phải 1):

┌─┐
│7│
└─┘

M :

┌──┐
│ 3│
│-1│
│ 4│
└──┘

V : 1 1 0( H phải 1)

Kết quả:

┌──┐
│ 3│
│-1│
│ 3│
└──┘

M :

┌───────────────────────────────────────────────────────┐
│10    7.7 1.9 1.5 5.4  1.2 7.8 0.6 4.3 1.2  4.5 5.4 0.3│
│ 2.3  3.8 4.1 4.5 1    7.7 3   3.4 6.9 5.8  9.5 1.3 7.5│
│ 9.1  3.7 7.2 9.8 3.9 10   7.6 9.6 7.3 6.2  3.3 9.2 9.4│
│ 4.3  4.9 7.6 2   1.4  5.8 8.1 2.4 1.1 2.3  7.3 3.6 6  │
│ 9.3 10   5.8 9.6 5.7  8.1 2.1 3.9 4   1.3  6.3 3.1 9  │
│ 6.6  1.4 0.5 6.5 4.6  2.1 7.5 4.3 9   7.2  2.8 3.6 4.6│
│ 1.7  9.9 2.4 4.5 1.3  2.6 6.4 7.8 6.2 3.2 10   5.2 8.9│
│ 9.9  5.3 4.5 6.3 1.4  3.1 2.3 7.9 7.8 7.9  9.6 4   5.8│
└───────────────────────────────────────────────────────┘

H :1 0 0 1 0 1 1 1 0 1 1 1 0

V :1 0 0 0 0 1 0 0

Kết quả:

┌────────────────────────────────────────────────────────────────┐
│10   17.7 19.6  1.5  6.9  1.2  7.8  0.6  4.9  1.2  4.5  5.4  5.7│
│12.3 23.8 29.8  6   12.4  8.9 10.8  4   15.2  7   14    6.7 14.5│
│21.4 36.6 49.8 15.8 26.1 18.9 18.4 13.6 32.1 13.2 17.3 15.9 33.1│
│25.7 45.8 66.6 17.8 29.5 24.7 26.5 16   35.6 15.5 24.6 19.5 42.7│
│35   65.1 91.7 27.4 44.8 32.8 28.6 19.9 43.5 16.8 30.9 22.6 54.8│
│ 6.6  8    8.5  6.5 11.1  2.1  7.5  4.3 13.3  7.2  2.8  3.6  8.2│
│ 8.3 19.6 22.5 11   16.9  4.7 13.9 12.1 27.3 10.4 12.8  8.8 22.3│
│18.2 34.8 42.2 17.3 24.6  7.8 16.2 20   43   18.3 22.4 12.8 32.1│
└────────────────────────────────────────────────────────────────┘

Câu trả lời:


9

Thạch , 10 byte

Zœṗ@+\€Ẏð/

Hãy thử trực tuyến! Trường hợp thử nghiệm cuối cùng (Với Gphần cuối cho khả năng đọc).

Đầu vào được lấy dưới dạng một danh sách [M, H, V].

Giải trình

Zœṗ@+\€Ẏð/  Input: [M, H, V]
        ð/  Insert the previous (f) as a dyadic link
            Forms f( f(M, H) , V)
            For f(x, y):
Z             Transpose x
 œṗ@          Partition the rows of x^T at each true in y
    +\€       Compute the cumulative sums in each partition
       Ẏ      Tighten (Joins all the lists at the next depth)

Bạn có thể sử dụng chân trang như thế này để không phải giả mạo mã thực tế của mình.
Erik the Outgolfer 27/07/17

7

APL (Dyalog) , 13 byte

Lấy ist của VHM làm đối số.

{⍉⊃,/+\¨⍺⊂⍵}/

Hãy thử trực tuyến!

{... }/ chèn (giảm) các chức năng sau đây mang tính chất trường hợp thời hạn ở bên trái được đại diện bởi ⍺ và thuật ngữ ở bên phải được thể hiện bằng ⍵. Do các chức năng APL là liên kết đúng, do đó đây là V f ( H f M ).

⍺⊂⍵ phân vùng theo ⍺

+\¨ tổng tích lũy của từng phần

,/ giảm bằng cách ghép (điều này kèm theo kết quả để giảm thứ hạng)

 tiết lộ

 hoán vị


6

Python 2 + numpy, 143 138 117 115 110 108 byte

-21 byte nhờ Adám !

lambda M,*L:reduce(lambda m,l:vstack(map(lambda p:cumsum(p,0),split(m,*where(l)))).T,L,M)
from numpy import*

Hãy thử trực tuyến!


1
yêu cầu phân vùng, phân tách và cumsum một lần, hoán vị, lặp lại.
Adám

@ Adám Cảm ơn, tôi đã không nghĩ về điều đó vì một số lý do.
notjagan

Dù sao thì tôi cũng thích danh sách tra cứu hai chức năng :)
Jonathan Allan

2
Vui lòng tạo tiêu đề "Python 3 + numpy"
Leaky Nun

5

Thạch ,  15  14 byte

œṗ+\€Ẏ
ḢçЀZð⁺

Một liên kết dyadic H,Vở bên trái và Mbên phải và trả về ma trận kết quả.

Hãy thử trực tuyến!

Ngoài ra, dưới dạng một dòng duy nhất cho 14: Ḣœṗ+\€Ẏ$¥Ð€Zð⁺

Làm sao?

œṗ+\€Ẏ - Link 1: partition and cumSum: list of partition bools, list of values
œṗ     - partition (the values) at truthy indexes (of the bools)
    €  - for €ach part:
  +\   -   cumulative reduce by addition
     Ẏ - tighten (flattens back into a list)

ḢçЀZð⁺ - Main link: list of lists, [H,V]; list of lists, M
      ⁺ - perform this twice:
     ð  - [it's a dyadic chain for the second pass, first pass is dyadic implicitly]
Ḣ       -   head, pop it & modify (so H the first time, V the second)
  Ѐ    -   map across right: (M the first time, the intermediate result the second)
 ç      -     the last link (1) as a dyad
    Z   -   transpose the result (do the rows first time, and the columns the second)

Trước:

œṗ@+\€Ẏ
ç€Zç€⁵Z

Một chương trình đầy đủ in một đại diện của kết quả.


Whoa -50% từ câu trả lời Jelly trước đây!
Adám

Whoa cái gì? Ồ Tôi thực sự cần nghiên cứu cách bạn đã làm điều này ... Thật đáng kinh ngạc so với của tôi!
HyperNeutrino

Oh đây là làm hai hướng riêng biệt, phải không? Thông minh.
HyperNeutrino

Tôi nghĩ rằng nó làm khoảng điều tương tự ...
Jonathan Allan

Phương pháp tốt. Có nghĩa là tôi có thể đánh bại điều này với APL. Tôi đã có 14 byte.
Adám

4

MATL , 19 byte

,!ix"0GYs@12XQ!g]v!

Các đầu vào là M(ma trận), H(vectơ cột), V(vectơ cột). Dấu phân cách hàng là ;.

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp kiểm tra: 1 , 2 , 3 , 4 , 5 .

Giải trình

Điều này không tổng tích lũy theo chiều ngang, sau đó theo chiều dọc.

,          % Do the following twice
  !        %   First time this inputs M implicitly. Transpose. Second time
           %   it transposes the result of the horizontal cumulative sum
  ix       %   Input H (first time) or V (second time). Delete it; but gets
           %   copied into clipboard G
  "        %   For each column of the matrix
    0G     %     Push most recent input: H (first time) or V (second)
    Ys     %     Cumulative sum. This produces a vector of integer values
           %     such that all columns (first time) or rows (second) of M 
           %     with the same value in this vector should be cumulatively
           %     summed
    @      %     Push current column of M transposed (first time) or M after
           %     horizontal cumulative sum (second time)
    12XQ   %     Cumulative sum. Gives a cell array of row vectors
    !g     %     Join those vectors into one row vector
  ]        %   End
  v        %   Concatenate the row vectors vertically into a matrix
  !        %   Transpose. This corrects for the fact that each column vector
           %   of the matrix was cumulatively summed into a row vector
           % Implicit end. Implicit display

1
Ấn tượng nhất. Tôi đoán Matlab đã được tạo ra cho những thứ như thế này.
Adám

@ Adám Tôi chắc chắn chiều dài của APL sẽ không khác lắm :-)
Luis Mendo

Việc thực hiện tham chiếu của tôi được sử dụng để tạo các trường hợp thử nghiệm là 26 byte.
Adám

@ Adám chết tiệt! APL đánh Jelly? Điều này là không thể chấp nhận được! (phải đánh golf giải pháp của tôi ... lol) xD
HyperNeutrino

@HyperNeutrino Chà, Jelly không có cả thứ hạng và chiều sâu như APL và J có.
Adám

3

J , 20 byte

;@(<@(+/\);.1|:)&.>/

Hãy thử trực tuyến!

Đầu vào được lấy dưới dạng một mảng các hộp chứa [V, H, M].

Giải trình

;@(<@(+/\);.1|:)&.>/  Input: [V H M]
  (     g      )   /  Insert g and reduce (right-to-left)
                      Forms V g H g M = V g (H g M)
                & >     Unbox each
             |:         Transpose the right arg
          ;.1           Partition
      +/\               Reduce each prefix using addition (cumulative sum)
   <@                   Box each partition
;@                      Raze (Concatenate the contents in each box)
                &.>     Box the result

2

Toán học, 212 byte

(T=Transpose;A=AppendTo;J=Flatten;f[s_]:=Block[{},t=2;r=1;w={};While[t<=Length@s,If[s[[t]]==0,r++,w~A~r;r=1];t++];w~A~r];K[x_,y_]:=Accumulate/@#&/@(FoldPairList[TakeDrop,#,f@y]&/@x);d=J/@K[#,#2];T[J/@K[T@d,#3]])&


đầu vào
[M, H, V]

[{{15, 11, 11, 17}, {13, 20, 18, 8}}, {1, 0, 0, 1}, {1, 0}]


2

C # (.NET Core) , 164 byte

(M,H,V)=>{int a=M.Length,b=M[0].Length,i,j;for(i=0;i<a;i++)for(j=0;j<b;j++)if(!H[j])M[i][j]+=M[i][j-1];for(i=0;i<a;i++)for(j=0;j<b;j++)if(!V[i])M[i][j]+=M[i-1][j];}

Hãy thử trực tuyến!

Về cơ bản, nó thực hiện chính xác như được chỉ định trong OP. Đầu tiên, nó lặp lại để tính tổng theo chiều ngang và sau đó lặp lại để tính tổng theo chiều dọc.


2

Haskell , 129 byte 119 byte

s m v=tail$scanl(\a(x,s)->if s then x else zipWith(+)a x)[](zip m v)
t=foldr(zipWith(:))$repeat[]
f m h v=t$s(t$s m v)h

Hãy thử trực tuyến!

Đã lưu 10 byte nhờ @ceasetoturnc gặpclockwis

t(cho chuyển vị) chuyển hàng và cột. Giải thích nhanh:

foldr(zipWith(:))(repeat[])(r1,...,rn) =
zipWith(:) r1 (zipWith(:) r2 (... zipWith(:) rn (repeat [])))

Đọc từ phải sang trái: chúng tôi duyệt các hàng từ dưới lên trên và đẩy từng giá trị trong cột đích của nó.

s về cơ bản là tổng các vectơ, nhưng đặt lại khi giá trị True xuất hiện trong v

ftính tổng các hàng với ssau vvà làm tương tự với các cột sauh


t=foldr(zipWith(:))(repeat[]). Không chỉ ngắn hơn, cũng kém hiệu quả hơn nhiều.
đã ngừng quay ngược chiều

@ceasetoturncountclockwis Cảm ơn vì tiền boa.
jferard

1

JavaScript (ES6), 88 byte

(a,h,v)=>a.map(b=>b.map((e,i)=>t=h[i]?e:t+e)).map((b,j)=>t=v[j]?b:t.map((e,i)=>e+b[i]))

0

Thạch , 31 byte

+\€€
œṗḊZ€⁵œṗ$€Ḋ€Ç€ÇZ€€Z€;/€€;/

Hãy thử trực tuyến!

Gah đây là quá dài cho Jelly xD

BTW, 11/31 byte trong chương trình này bao gồm các ký tự euro. Đó là hơn một phần ba của chương trình!


Quá nhiều Euro.
Adám

@ Adám Chính xác là suy nghĩ của tôi: P Làm việc với các ma trận được phân vùng gấp đôi không thú vị như tôi nghĩ, bởi vì tôi đang thực hiện ánh xạ cấp hai đến cấp ba xD
HyperNeutrino

Tại sao bạn lại lãng phí tiền của mình như thế này € - €
V. Courtois
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.