2D分区累计总和


16

挑战

给定的矩阵中号[R行和C ^列和两个布尔列表V长度的řħ长度的Ç,计算所述划分累积的垂直和水平的和。

规则

  • rc大于或等于1

  • HV以真实值开头

  • M中的值在您语言的合理数值范围内。

  • 分区和求和从左上角开始。

穿过

给定M

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

1 0 1 0 0

V1 1 0 1

M分为几列,以H的每个真实值开始一个新的组

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

将每组列分成几组行,从V的每个真值开始一个新的组:

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

累计水平汇总每个单元格:

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

垂直累计每个单元格:

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

结果:

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

其他测试用例

M

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

^ h1 0 0 1V1 0

结果:

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

M

┌─┐
│7│
└─┘

结果(HV必须为1):

┌─┐
│7│
└─┘

M

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

V1 1 0H必须是1

结果:

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

1 0 0 1 0 1 1 1 0 1 1 1 0

V1 0 0 0 0 1 0 0

结果:

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

Answers:


9

果冻,10字节

Zœṗ@+\€Ẏð/

在线尝试!最后一个测试用例 (以G可读性结尾)。

输入被视为列表[M, H, V]

说明

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)

你可以使用像一个页脚使你不必用你的实际代码篡改。
暴民埃里克(Erik the Outgolfer)

7

APL(Dyalog),13个字节

VHM的 ist 作为参数。

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

在线尝试!

{}/ 插入(减少)以下匿名函数,其中左边的术语由represented表示,右边的术语由represented表示。由于APL功能正确关联,因此这是V fH f M)。

⍺⊂⍵ 根据⍺划分⍵

+\¨ 各部分的累计和

,/ 通过串联减少(这将结果括起来以降低等级)

 透露

 转置


6

蟒2 + numpy的,143 138 117 115 110 108个字节

感谢Adám -21个字节!

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

在线尝试!


1
要求分区,分割和累加一次,转置,重复一次。
亚当

@Adám谢谢,出于某些原因,我没有想到这一点。
notjagan

无论如何,我还是喜欢两个函数的列表查找:)
Jonathan Allan

2
请设置标题“ Python 3 + numpy”
Leaky Nun

5

果冻 15  14 字节

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

二元链接H,V在左边和M右边进行,并返回结果矩阵。

在线尝试!

或者也可以单行显示14: Ḣœṗ+\€Ẏ$¥Ð€Zð⁺

怎么样?

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

以前:

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

完整程序打印结果表示。


哇,以前的果冻答案是-50%!
亚当

哇 哇。我真的需要研究您是如何做到的……与我的相比令人难以置信!
HyperNeutrino

哦,这是分别做两个方向的,对吧?聪明。
HyperNeutrino

我认为它的作用大致相同...
Jonathan Allan

好方法 意味着我可以使用APL击败它。我有14个字节。
亚当

4

MATL,19字节

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

输入为M(矩阵),H(列向量),V(列向量)。行分隔符为;

在线尝试!或验证所有测试情况:12345

说明

这将在水平方向然后在垂直方向进行累加和。

,          % 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
最令人印象深刻。我猜Matlab有点像这样的东西。
亚当

@Adám我确定APL的长度不会有很大不同:-)
Luis Mendo

我用来生成测试用例的参考实现是26个字节。
亚当

@AdámDarn!APL击败果冻?这是无法接受的!(必须高尔夫球我的解决方案...大声笑)xD
HyperNeutrino

@HyperNeutrino好吧,Jelly不像APL和J那样拥有等级和深度。
亚当

3

J,20个字节

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

在线尝试!

输入被视为包含以下内容的框的数组 [V, H, M]

说明

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

(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]])&


输入
[M,H,V]

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


2

C#(.NET Core),164字节

(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];}

在线尝试!

基本上,它完全按照OP中的规定执行。它首先迭代进行水平求和,然后再次迭代进行垂直求和。


2

Haskell129字节 119字节

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

在线尝试!

@ceasedtoturncounterclockwis,节省了10个字节

t(用于转置)切换行和列。快速说明:

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

从右到左阅读:我们从下至上浏览行,并将每个值推入其目标列。

s 基本上是向量的滚动总和,但是当在其中出现True值时会重置 v

fs以下各行相加,并对以下v各列进行相同的操作h


t=foldr(zipWith(:))(repeat[])。不仅更短,而且效率更低。

@ceasedtoturncounterclockwis感谢您的提示。
jferard '17

1

JavaScript(ES6),88个字节

(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

果冻,31个字节

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

在线尝试!

Gah对于Jelly xD来说太长了

顺便说一句,此程序中的11/31个字节由欧元字符组成。超过程序的三分之一!


太多欧元。
亚当

@Adám我的想法正好:P使用双重分区矩阵并不像我想象的那样有趣,因为我正在进行第二级到第三级映射xD
HyperNeutrino

您为什么要这样浪费您的钱?
V. Courtois
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.