Jumlah kumulatif yang dipartisi 2D


16

Tantangan

Diberi matriks M dengan r rows dan c kolom, dan dua daftar Boolean V panjang r dan H panjang c , hitung jumlah kumulatif vertikal dan horizontal yang dipartisi.

Aturan

  • r dan c lebih besar dari atau sama dengan satu

  • H dan V dimulai dengan nilai sebenarnya

  • Nilai dalam M berada dalam domain numerik wajar bahasa Anda.

  • Partisi dan penjumlahan dimulai di sudut kiri atas.

Berjalan melalui

Diberikan 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

Membagi M menjadi grup kolom, memulai grup baru di setiap nilai sebenarnya dari H

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

Pisahkan setiap grup kolom menjadi grup baris, mulai grup baru di setiap nilai sebenarnya dari V :

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

Secara kumulatif jumlah setiap sel secara horizontal:

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

Secara kumulatif jumlah setiap sel secara vertikal:

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

Hasil:

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

Kasus uji tambahan

M :

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

H : 1 0 0 1V :1 0

Hasil:

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

M :

┌─┐
│7│
└─┘

Hasil ( H dan V harus 1):

┌─┐
│7│
└─┘

M :

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

V : 1 1 0( H harus 1)

Hasil:

┌──┐
│ 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

Hasil:

┌────────────────────────────────────────────────────────────────┐
│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│
└────────────────────────────────────────────────────────────────┘

Jawaban:


9

Jelly , 10 byte

Zœṗ@+\€Ẏð/

Cobalah online! dan Kasus Tes Terakhir (Dengan aG di bagian akhir agar mudah dibaca).

Masukan diambil sebagai daftar [M, H, V] .

Penjelasan

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)

Anda dapat menggunakan catatan kaki seperti ini sehingga Anda tidak perlu mengutak-atik kode aktual Anda.
Erik the Outgolfer

7

APL (Dyalog) , 13 byte

Mengambil VHM sebagai argumen.

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

Cobalah online!

{... }/ masukkan (kurangi dengan) fungsi anonim berikut, di mana istilah di sebelah kiri diwakili oleh ⍺ dan istilah di sebelah kanan diwakili oleh ⍵. Karena fungsi APL menjadi asosiatif yang tepat, ini karena itu V f ( H f M ).

⍺⊂⍵ partisi ⍵ menurut ⍺

+\¨ jumlah kumulatif dari setiap bagian

,/ kurangi dengan penyatuan (ini melingkupi hasil untuk mengurangi peringkat)

 membuka

 mengubah urutan


6

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

-21 bytes terima kasih kepada 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*

Cobalah online!


1
minta partisi, pisahkan, dan kumsum sekali, transpos, ulangi.
Adám

@ Adám Terima kasih, saya tidak memikirkan itu untuk beberapa alasan.
notjagan

Saya menyukai daftar pencarian dari dua fungsi sih :)
Jonathan Allan

2
Silakan buat tajuk "Python 3 + numpy"
Leaky Nun

5

Jelly ,  15  14 byte

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

Sebuah link diad mengambil H,Vdi kiri dan Mdi kanan dan mengembalikan matriks yang dihasilkan.

Cobalah online!

Atau sebagai satu baris juga untuk 14: Ḣœṗ+\€Ẏ$¥Ð€Zð⁺

Bagaimana?

œṗ+\€Ẏ - 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)

Sebelumnya:

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

Program lengkap mencetak representasi hasil.


Whoa -50% dari jawaban Jelly sebelumnya!
Adám

Apa? Wow. Saya benar-benar perlu mempelajari bagaimana Anda melakukan ini ... Luar biasa dibandingkan dengan milik saya!
HyperNeutrino

Oh ini melakukan dua arah secara terpisah, kan? Pintar.
HyperNeutrino

Saya pikir itu melakukan hal yang kira - kira sama ...
Jonathan Allan

Metode yang bagus Berarti saya bisa mengalahkan ini dengan APL. Saya mendapat 14 byte.
Adám

4

MATL , 19 byte

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

Inputnya adalah M(matriks), H(vektor kolom), V(vektor kolom). Pemisah baris adalah ;.

Cobalah online! Atau verifikasi semua kasus uji: 1 , 2 , 3 , 4 , 5 .

Penjelasan

Ini melakukan penjumlahan kumulatif secara horizontal, kemudian secara vertikal.

,          % 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
Paling mengesankan. Saya kira Matlab agak dibuat untuk hal-hal seperti ini.
Adám

@ Adám, saya yakin panjang APL tidak akan jauh berbeda :-)
Luis Mendo

Implementasi referensi saya yang digunakan untuk menghasilkan kasus uji adalah 26 byte.
Adám

@ Adám Darn! APL mengalahkan Jelly? Ini tidak bisa diterima! (harus golf solusi saya ... lol) xD
HyperNeutrino

@HyperNeutrino Ya, Jelly tidak memiliki peringkat dan kedalaman seperti APL dan J miliki.
Adám

3

J , 20 byte

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

Cobalah online!

Input diambil sebagai larik kotak yang berisi [V, H, M].

Penjelasan

;@(<@(+/\);.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

Mathematica, 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]])&


masukan
[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];}

Cobalah online!

Pada dasarnya itu tidak persis seperti yang ditentukan dalam OP. Pertama iterates untuk menjumlahkan secara horizontal dan kemudian iterates lagi untuk menjumlahkan secara vertikal.


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

Cobalah online!

Disimpan 10 byte berkat @ceasedtoturncounterclockwis

t(untuk transpose) beralih baris dan kolom. Penjelasan singkat:

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

Baca dari kanan ke kiri: kami menelusuri baris dari bawah ke atas, dan mendorong setiap nilai di kolom tujuan.

s pada dasarnya adalah jumlah bergulir dari vektor, tetapi me-reset ketika nilai True muncul v

fmenjumlahkan baris dengan smengikuti vdan melakukan hal yang sama dengan kolom berikuth


t=foldr(zipWith(:))(repeat[]). Tidak hanya lebih pendek, juga jauh lebih tidak efisien.
Berhenti menghidupkan counterclock dengan

@ceasedtoturncounterclockw Terima kasih atas tipnya.
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

Jelly , 31 byte

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

Cobalah online!

Gah ini terlalu lama untuk Jelly xD

BTW, 11/31 byte dalam program ini terdiri dari karakter euro. Itu lebih dari sepertiga program!


Euro terlalu banyak.
Adám

@ Adám Pikiran saya persis: P Bekerja dengan matriks yang dipartisi dua kali tidak semenyenangkan yang saya kira, karena saya sedang melakukan pemetaan tingkat kedua hingga tingkat ketiga xD
HyperNeutrino

Mengapa Anda membuang-buang uang seperti ini € - €
V. Courtois
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.