Somme cumulée 2D partitionnée

16

Défi

Étant donné une matrice M avec r lignes et colonnes c , et deux listes booléennes V de longueur r et H de longueur c , calculez les sommes cumulées verticales et horizontales partitionnées.

Règles

  • r et c sont supérieurs ou égaux à un

  • H et V commencent par une vraie valeur

  • Les valeurs de M se trouvent dans le domaine numérique raisonnable de votre langue.

  • Le partitionnement et la sommation commencent dans le coin supérieur gauche.

Procédure pas à pas

Étant donné 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

Fractionner M en groupes de colonnes, en commençant un nouveau groupe à chaque vraie valeur de H

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

Divisez chaque groupe de colonnes en groupes de lignes, en commençant un nouveau groupe à chaque vraie valeur de V :

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

Additionnez chaque cellule horizontalement:

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

Additionnez cumulativement chaque cellule verticalement:

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

Résultat:

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

Cas de test supplémentaires

M :

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

H : 1 0 0 1V :1 0

Résultat:

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

M :

┌─┐
│7│
└─┘

Résultat ( H et V doivent être 1):

┌─┐
│7│
└─┘

M :

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

V : 1 1 0( H doit être 1)

Résultat:

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

Résultat:

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

Réponses:

9

Gelée , 10 octets

Zœṗ@+\€Ẏð/

Essayez-le en ligne! et le dernier cas de test (avec unG à la fin pour la lisibilité).

L'entrée est considérée comme une liste [M, H, V] .

Explication

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)
miles
la source
Vous pouvez utiliser un pied de page comme celui-ci afin de ne pas avoir à altérer votre code réel.
Erik the Outgolfer
7

APL (Dyalog) , 13 octets

Prend ist de VHM comme argument.

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

Essayez-le en ligne!

{}/ Insérer (réduire de) la fonction anonyme suivante, où le terme à gauche est représenté par ⍺ et le terme à droite est représenté par ⍵. Du fait que les fonctions APL sont associatives à droite, il s'agit donc de V f ( H f M ).

⍺⊂⍵ partition ⍵ selon ⍺

+\¨ somme cumulée de chaque partie

,/ réduire par concaténation (ceci renferme le résultat pour réduire le rang)

 divulguer

 transposer

Adam
la source
6

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

-21 octets grâce à 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*

Essayez-le en ligne!

notjagan
la source
1
demander la partition, le split et le cumsum une fois, transposer, répéter.
Adám
@ Adám Merci, je n'y ai pas pensé pour une raison quelconque.
notjagan
J'ai quand même aimé la liste de recherche de deux fonctions :)
Jonathan Allan
2
Veuillez faire l'en-tête "Python 3 + numpy"
Leaky Nun
5

Gelée ,  15  14 octets

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

Un lien dyadique prenant H,Và gauche et Mà droite et renvoyant la matrice résultante.

Essayez-le en ligne!

Alternativement en une seule ligne également pour 14: Ḣœṗ+\€Ẏ$¥Ð€Zð⁺

Comment?

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

Précédent:

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

Un programme complet imprimant une représentation du résultat.

Jonathan Allan
la source
Whoa -50% de la réponse précédente de Jelly!
Adám
Whoa quoi? Sensationnel. J'ai vraiment besoin d'étudier comment tu as fait ça ... Incroyable par rapport au mien!
HyperNeutrino
Oh, cela fait les deux directions séparément, non? Intelligent.
HyperNeutrino
Je pense que ça fait à peu près la même chose ...
Jonathan Allan
Bonne méthode. Signifie que je peux battre cela avec APL. J'ai 14 octets.
Adám
4

MATL , 19 octets

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

Les entrées sont M(matrice), H(vecteur de colonne), V(vecteur de colonne). Le séparateur de lignes est ;.

Essayez-le en ligne! Ou vérifiez tous les cas de test: 1 , 2 , 3 , 4 , 5 .

Explication

Cela fait la somme cumulée horizontalement, puis verticalement.

,          % 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
Luis Mendo
la source
1
Plus impressionnant. Je suppose que Matlab était un peu fait pour des trucs comme ça.
Adám
@ Adám, je suis sûr que la longueur de l'APL ne sera pas très différente :-)
Luis Mendo
Mon implémentation de référence utilisée pour générer les cas de test est de 26 octets.
Adám
@ Adám Darn! APL bat Jelly? C'est inacceptable! (doit
jouer au
@HyperNeutrino Eh bien, Jelly n'a ni rang ni profondeur comme APL et J.
Adám
3

J , 20 octets

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

Essayez-le en ligne!

L'entrée est considérée comme un tableau de cases contenant [V, H, M] .

Explication

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

Mathematica, 212 octets

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


entrée
[M, H, V]

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

J42161217
la source
2

C # (.NET Core) , 164 octets

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

Essayez-le en ligne!

Fondamentalement, il fait exactement comme spécifié dans l'OP. Il réitère d'abord pour additionner horizontalement puis il réitère pour additionner verticalement.

Charlie
la source
2

Haskell , 129 octets 119 octets

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

Essayez-le en ligne!

10 octets enregistrés grâce à @ceasedtoturncounterclockwis

t(pour la transposition) change de ligne et de colonne. Une explication rapide:

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

Lire de droite à gauche: nous parcourons les lignes de bas en haut et poussons chaque valeur dans sa colonne de destination.

s est essentiellement une somme glissante de vecteurs, mais se réinitialise lorsqu'une valeur True apparaît dans v

fadditionne les lignes avec ce qui ssuit vet fait de même avec les colonnes suivantesh

jferard
la source
t=foldr(zipWith(:))(repeat[]). Non seulement plus court, mais aussi beaucoup moins inefficace.
cessé de tourner dans le sens inverse des aiguilles d'une montre le
@ceasedtoturncounterclockwis Merci pour le conseil.
jferard
1

JavaScript (ES6), 88 octets

(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]))
Neil
la source
0

Gelée , 31 octets

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

Essayez-le en ligne!

Gah c'est trop long pour Jelly xD

BTW, 11/31 octets dans ce programme se compose de caractères euro. C'est plus d'un tiers du programme!

HyperNeutrino
la source
Trop d'euros.
Adám
@ Adám Mes pensées exactement: P Travailler avec des matrices doublement partitionnées n'est pas aussi amusant que je le pensais, car je fais du mappage de deuxième à troisième niveaux xD
HyperNeutrino
Pourquoi gaspillez-vous votre argent comme ça € - €
V. Courtois