2D 분할 누적 합계


16

도전

매트릭스 주어 MR의 행과 C의 컬럼 및 2 개의 부울을 나열 V 길이의 RH 길이의 C , 분할 된 누적 종횡 합을 계산한다.

규칙

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

H :1 0 1 0 0

V :1 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│
└───────────┘

H : 1 0 0 1V :1 0

결과:

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

M :

┌─┐
│7│
└─┘

결과 ( HV 는이어야 함 1) :

┌─┐
│7│
└─┘

M :

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

V : 1 1 0( H 는이어야 함 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│
└───────────────────────────────────────────────────────┘

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

V :1 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│
└────────────────────────────────────────────────────────────────┘

답변:


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)

당신은 같은 바닥 글 사용 당신이 당신의 실제 코드 함부로 변경하지 않아도됩니다.
Outgolfer Erik

7

APL (Dyalog) , 13 바이트

VHM의 ist를 인수로 사용합니다.

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

온라인으로 사용해보십시오!

{}/ 왼쪽의 용어는 ⍺로 표시되고 오른쪽의 용어는 ⍵로 표시되는 다음 익명 함수를 삽입 (감소)합니다. APL 기능이 올바르게 연관되어 있기 때문에 이것은 V f ( H 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

@ Adám 감사합니다, 나는 어떤 이유로 든 생각하지 않았습니다.
notjagan

어쨌든 두 함수의 목록 조회가 마음에 들었습니다 :)
Jonathan Allan

2
헤더 "Python 3 + numpy"
Leaky Nun

5

젤리 ,  15  14 바이트

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

H,V왼쪽과 M오른쪽을 가져와 결과 행렬을 반환 하는 2 차원 링크 입니다.

온라인으로 사용해보십시오!

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 %!
Adám

우와 뭐? 와. 나는 당신이 이것을 어떻게했는지 연구해야합니다 ... 내 것과 비교할 때 놀라운!
HyperNeutrino

아, 이것은 두 가지 방향을 따로하고 있습니다. 똑똑한.
HyperNeutrino

나는 그것이 거의 같은 일을 하고 있다고 생각합니다 ...
Jonathan Allan

좋은 방법입니다. 내가 APL로 이것을 이길 수 있음을 의미합니다. 14 바이트가 있습니다.
Adám

4

MATL , 19 바이트

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

입력은 M(행렬), H(열 벡터), V(열 벡터)입니다. 행 구분 기호는 ;입니다.

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 : 1 , 2 , 3 , 4 , 5 .

설명

이것은 누적 합계를 수평으로 한 다음 수직으로 수행합니다.

,          % 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

@ Adám 나는 APL의 길이가 크게 다르지 않을 것이라고 확신한다 :-)
Luis Mendo

테스트 사례를 생성하는 데 사용 된 참조 구현은 26 바이트입니다.
Adám

@ Adám Darn! 젤리를 때리는 APL? 용납 할 수 없습니다! xD
HyperNeutrino

@HyperNeutrino 음, Jelly는 APL이나 J처럼 순위와 깊이를 모두 가지고 있지 않습니다.
Adám

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

수학, 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 코어) 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

하스켈 , 129 바이트 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

f행을 s다음 v과 합산하고 다음 열과 동일하게 수행h


t=foldr(zipWith(:))(repeat[]). 더 짧을뿐만 아니라 훨씬 덜 비효율적입니다.
반 시계 회전 중지

@ceasedtoturncounterclockwis 팁 주셔서 감사합니다.
jferard

1

자바 스크립트 (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에게는 너무 길다

BTW,이 프로그램에서 11/31 바이트는 유로 문자로 구성됩니다. 프로그램의 3 분의 1 이상입니다!


유로가 너무 많습니다.
Adám

@ Adám 내 생각은 정확히 : P 이중 분할 행렬로 작업하는 것은 생각보다 재미 있지 않습니다. 왜냐하면 2 단계에서 3 단계로 매핑하기 xD
HyperNeutrino

왜 당신이 €-€
V. Courtois
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.