Somma cumulativa partizionata 2D


16

Sfida

Data una matrice M con r righe e colonne c e due elenchi booleani V di lunghezza r e H di lunghezza c , calcolare le somme cumulative verticali e orizzontali ripartite.

Regole

  • r e c sono maggiori o uguali a uno

  • H e V iniziano con un valore vero

  • I valori in M sono all'interno del dominio numerico ragionevole della tua lingua.

  • Il partizionamento e la somma iniziano nell'angolo in alto a sinistra.

Procedura dettagliata

Dato 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

Dividi M in gruppi di colonne, iniziando un nuovo gruppo ad ogni vero valore di H

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

Dividi ogni gruppo di colonne in gruppi di righe, iniziando un nuovo gruppo ad ogni vero valore di V :

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

Sommare cumulativamente ogni cella in orizzontale:

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

Sommare cumulativamente ogni cella in verticale:

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

Risultato:

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

Casi di prova aggiuntivi

M :

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

H : 1 0 0 1V :1 0

Risultato:

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

M :

┌─┐
│7│
└─┘

Risultato ( H e V devono essere 1):

┌─┐
│7│
└─┘

M :

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

V : 1 1 0( H deve essere 1)

Risultato:

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

Risultato:

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

Risposte:


9

Gelatina , 10 byte

Zœṗ@+\€Ẏð/

Provalo online! e The Last Test Case (con Ga alla fine per leggibilità).

L'input viene considerato come un elenco [M, H, V].

Spiegazione

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)

Puoi usare un piè di pagina come questo in modo da non dover manomettere il tuo codice attuale.
Erik the Outgolfer,

7

APL (Dyalog) , 13 byte

Prende istanza di VHM come argomento.

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

Provalo online!

{... }/ inserire (ridurre di) la seguente funzione anonima, in cui il termine a sinistra è rappresentato da ⍺ e il termine a destra è rappresentato da ⍵. Poiché le funzioni APL sono associative giuste, questo è quindi V f ( H f M ).

⍺⊂⍵ partizione ⍵ secondo ⍺

+\¨ somma cumulativa di ogni parte

,/ ridurre per concatenazione (questo racchiude il risultato per ridurre il rango)

 divulgare

 trasporre


6

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

-21 byte grazie ad 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*

Provalo online!


1
chiedere una volta partizione, divisione e cumsum, trasporre, ripetere.
Adám,

@Adám Grazie, non ci ho pensato per qualche motivo.
notjagan,

Mi è piaciuta comunque la ricerca dell'elenco di due funzioni :)
Jonathan Allan,

2
Per favore fai l'intestazione "Python 3 + numpy"
Leaky Nun il

5

Gelatina ,  15  14 byte

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

Un collegamento diadico che prende H,Va sinistra ea Mdestra e restituisce la matrice risultante.

Provalo online!

In alternativa come linea singola anche per 14: Ḣœṗ+\€Ẏ$¥Ð€Zð⁺

Come?

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

Precedente:

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

Un programma completo che stampa una rappresentazione del risultato.


Whoa -50% dalla precedente risposta di Jelly!
Adám,

Whoa cosa? Wow. Ho davvero bisogno di studiare come hai fatto questo ... Incredibile rispetto al mio!
HyperNeutrino,

Oh, questo sta facendo le due direzioni separatamente, giusto? Inteligente.
HyperNeutrino,

Penso che stia facendo all'incirca la stessa cosa ...
Jonathan Allan,

Buon metodo. Significa che posso batterlo con APL. Ho 14 byte.
Adám,

4

MATL , 19 byte

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

Gli input sono M(matrice), H(vettore colonna), V(vettore colonna). Il separatore di riga è ;.

Provalo online! Oppure verifica tutti i casi di test: 1 , 2 , 3 , 4 , 5 .

Spiegazione

Questo fa la somma cumulativa in orizzontale, quindi in verticale.

,          % 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
Più impressionante. Immagino che Matlab sia stato creato per cose come questa.
Adám,

@Adám Sono sicuro che la lunghezza di APL non sarà molto diversa :-)
Luis Mendo,

La mia implementazione di riferimento utilizzata per generare i casi di test è di 26 byte.
Adám,

@ Adám Darn! APL batte Jelly? Questo è inaccettabile! (devo golf la mia soluzione ... lol) xD
HyperNeutrino,

@HyperNeutrino Bene, Jelly non ha sia rango che profondità come APL e J hanno.
Adám,

3

J , 20 byte

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

Provalo online!

L'input viene preso come una matrice di scatole contenenti [V, H, M].

Spiegazione

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


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

Provalo online!

Fondamentalmente fa esattamente come specificato nel PO. Prima scorre per sommare in orizzontale e poi ripeterà per sommare in verticale.


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

Provalo online!

10 byte salvati grazie a @ceasedtoturncounterclockwis

t(per trasporre) cambia righe e colonne. Una breve spiegazione:

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

Leggi da destra a sinistra: sfogliamo le righe dal basso verso l'alto e spingiamo ogni valore nella sua colonna di destinazione.

s è fondamentalmente una somma variabile di vettori, ma si reimposta quando sorge un valore True v

fsomma le righe con il sseguente ve fai lo stesso con le colonne seguentih


t=foldr(zipWith(:))(repeat[]). Non solo più breve, ma anche molto meno inefficiente.
cessò di girare in senso antiorario il

@ceasedtoturncounterclockwis Grazie per la punta.
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

Gelatina , 31 byte

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

Provalo online!

Gah, questo è troppo lungo per Jelly xD

A proposito, 11/31 byte in questo programma è composto da caratteri in euro. Questo è oltre un terzo del programma!


Troppi euro.
Adám,

@ Adám I ​​miei pensieri esattamente: P Lavorare con matrici doppiamente divise non è così divertente come pensavo, perché sto facendo una mappatura dal secondo livello al terzo livello xD
HyperNeutrino,

Perché stai sprecando i tuoi soldi in questo modo € - €
V. Courtois,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.