Trasmissione modulare


24

Questa sfida è legata ad alcune delle funzionalità del linguaggio MATL, nell'ambito dell'evento Lingua del mese di maggio 2018 .


introduzione

In MATL, molte funzioni a due input funzionano in modo elementare con la trasmissione . Ciò significa quanto segue:

  • Per quanto riguarda gli elementi (o vettorializzati ): la funzione accetta come input due array con dimensioni corrispondenti. L'operazione definita dalla funzione viene applicata a ciascuna coppia di voci corrispondenti. Ad esempio, usando la notazione post-correzione:

    [2 4 6] [10 20 30] +
    

    il risultato

    [12 24 36]
    

    Questo funziona anche con array multidimensionali. La notazione [1 2 3; 4 5 6]rappresenta la matrice 2× 3(matrice)

    1 2 3
    4 5 6
    

    che ha dimensioni 2lungo la prima dimensione (verticale) e 3lungo la seconda (orizzontale). Quindi per esempio

    [2 4 6; 3 5 7] [10 20 30; 40 60 80] *
    

    [20 80 180; 120 300 560]
    
  • Trasmissione o ( espansione singleton ): i due array di input non hanno dimensioni corrispondenti, ma in ciascuna dimensione non corrispondente uno degli array ha dimensione 1. Questo array viene replicato implicitamente lungo le altre dimensioni per far corrispondere le dimensioni; e quindi l'operazione viene applicata come elemento sopra. Ad esempio, considerare due array di input con dimensioni 1× 2e 3× 1:

    [10 20] [1; 2; 5] /
    

    Grazie alla trasmissione, questo equivale a

    [10 20; 10 20; 10 20] [1 1; 2 2; 5 5] /
    

    e così

    [10 20; 5 10; 2 4]
    

    Allo stesso modo, con le dimensioni 3× 2e 3× 1(la trasmissione ora agisce solo lungo la seconda dimensione),

    [9 8; 7 6; 5 4] [10; 20; 30] +
    

    [19 18; 27 26; 35 34]
    

    Il numero di dimensioni può anche essere diverso. Ad esempio, gli ingressi con dimensioni 3 × 2 e 3 × 1 × 5 sono compatibili e danno un risultato 3 × 2 × 5. In effetti, la dimensione 3 × 2 è la stessa di 3 × 2 × 1 (ci sono arbitrariamente molte dimensioni singleton finali implicite).

    D'altra parte, una coppia di matrici 2× 2e 3× 1darebbe un errore, perché le dimensioni lungo la prima dimensione sono 2e 3: non sono uguali e nessuna di esse lo è 1.

Definizione di broadcasting modulare

La trasmissione modulare è una generalizzazione della trasmissione che funziona anche se nessuna delle dimensioni non corrispondenti lo sono 1. Consideriamo ad esempio i seguenti array 2× 2e 3× 1come input della funzione +:

[2 4; 6 8] [10; 20; 30] +

La regola è la seguente: per ogni dimensione, l'array più piccolo lungo quella dimensione viene replicato in modo modulare (ciclicamente) per corrispondere alla dimensione dell'altro array. Ciò renderebbe quanto sopra equivalente

[2 4; 6 8; 2 4] [10 10; 20 20; 30 30] +

con il risultato

[12 14; 26 28; 32 34]

Come secondo esempio,

[5 10; 15 20] [0 0 0 0; 1 2 3 4; 0 0 0 0; 5 6 7 8; 0 0 0 0] +

produrrebbe

[5 10 5 10; 16 22 18 24; 5 10 5 10; 20 26 22 28; 5 10 5 10]

In generale, gli input con dimensioni a× be c× ddanno un risultato di dimensione max(a,b)× max(c,d).

La sfida

Implementare l' aggiunta per array bidimensionali con broadcasting modulare come definito sopra.

Le matrici saranno rettangolari (non irregolari), conterranno solo numeri interi non negativi e avranno dimensioni almeno1 in ogni dimensione.

Regole Adizionali:

Casi test

Quanto segue utilizza ;come separatore di righe (come negli esempi sopra). Ogni test case mostra i due ingressi e quindi l'uscita.

[2 4; 6 8]
[10; 20; 30]
[12 14; 26 28; 32 34]

[5 10; 15 20]
[0 0 0 0; 1 2 3 4; 0 0 0 0; 5 6 7 8; 0 0 0 0]
[5 10 5 10; 16 22 18 24; 5 10 5 10; 20 26 22 28; 5 10 5 10]

[1]
[2]
[3]

[1; 2]
[10]
[11; 12]

[1 2 3 4 5]
[10 20 30]
[11 22 33 14 25]

[9 12 5; 5 4 2]
[4 2; 7 3; 15 6; 4 0; 3 3]
[13 14 9;12 7 9;24 18 20;9 4 6;12 15 8]

[9 12 5; 5 4 2]
[4 2 6 7; 7 3 7 3; 15 6 0 1; 4 0 1 16; 3 3 3 8]
[13 14 11 16; 12 7 9 8; 24 18 5 10; 9 4 3 21; 12 15 8 17]

[6 7 9]
[4 2 5]
[10 9 14]

"Implementa aggiunta per array bidimensionali": esistono casi di test monodimensionali.
Jonathan Allan,

Possiamo presumere che non riceviamo input di array irregolari? (sembra così)
Jonathan Allan,

1
@JonathanAllan Ci scusiamo per non essere stato chiaro. Sì, non puoi assumere matrici irregolari. Saranno matrici rettangolari. Quelle "monodimensionali" dovrebbero essere considerate bidimensionali con dimensioni 1× n(come [1 2 3]) o n× 1(come [1; 2; 3])
Luis Mendo,

La trasmissione che descrivi sembra più limitata della trasmissione MATLAB o NumPy; nella descrizione, gli input devono avere lo stesso numero di dimensioni, una restrizione non presente in MATLAB o NumPy. Si tratta di una restrizione MATL o di una semplificazione ai fini della sfida (poiché la sfida è limitata all'input 2D)?
user2357112 supporta Monica

@ user2357112 Sì, è stata una semplificazione nella descrizione. La trasmissione di MATL è la stessa di MATLAB: puoi avere ingressi 3 × 2 e 3 × 1 × 5 e ottenere un risultato 3 × 2 × 5. In realtà, 3 × 2 equivale a 3 × 2 × 1 (dimensioni finali implicite). Penso che sia simile in Numpy (ma con dimensioni iniziali). L'ho chiarito nell'introduzione
Luis Mendo

Risposte:


4

Gelatina , 10 byte

ṁ€ZL$Z€Ɗ⁺S

Accetta una coppia di matrici (due matrici di righe) come input e restituisce una matrice.

Provalo online!

Come funziona

ṁ€ZL$Z€Ɗ⁺S  Main link. Argument: [M, N] (matrix pair)

  Z $       Zip M with N (i.e., transpose the matrix of arrays [M, N], ...
   L            then take the length (number of rows) of the result.
ṁ€          Mold M and N like the indices, cyclically repeating their rows as many
            times as needed to reach the length to the right.
     Z€     Zip each; transpose both M and N.
       Ɗ⁺   Combine the three links to the left into a chain and duplicate it.
            The first run enlarges the columns, the second run the rows.
         S  Take the sum of the modified matrices.

1
Certo ... vedo tutti questi linguaggi del golf come in qualche modo compatibili in termini di byte necessari per una sfida (Jelly, 05AB1E, Pyth, APL, ecc.) La maggior parte delle risposte attuali sono di circa 20 byte, e qui arriva il Mago Dennis con una risposta dimezzata di quello ..;) Abbastanza divertente quando meme e verità sono la stessa cosa: " Nessuno supera i Dolf! .. "
Kevin Cruijssen,

1
@KevinCruijssen APL non è una lingua da golf.
Adám,

1
@ Adám Lo so, lo so. Ma è ancora molto breve (nonostante sia stato sviluppato per la prima volta negli anni '60). Forse avrei dovuto dire lingue brevi anziché lingue da golf. Ah bene ..
Kevin Cruijssen

5

Carbone , 25 23 byte

AθIE⌈EθLιE⌈EθL§λ⁰ΣE觧νιλ

Provalo online! Il collegamento è alla versione dettagliata del codice. Accetta input come un array tridimensionale. Spiegazione:

Aθ

Inserisci tutto.

    θ                   Input
   E                    Map over arrays
      ι                 Current array
     L                  Length
  ⌈                     Maximum
 E                      Map over implicit range
          θ             Input
         E              Map over arrays
             λ          Current array
            § ⁰         First element
           L            Length
        ⌈               Maximum
       E                Map over implicit range
                 θ      Input
                E       Map over arrays
                    ν   Current array
                   § ι  Cyclically index using outer loop index
                  §   λ Cyclically index using inner loop index
               Σ        Sum
I                       Cast to string
                        Implicitly print on separate lines and paragraphs

: P (è più lungo però> _>)
ASCII l'

5

MATL , 25 24 byte

,iZy]vX>XKx,@GK:KP:3$)]+

Provalo online!

Finalmente! Ci è voluta solo una settimana per rispondere alla sfida ispirata alla Lingua del mese!

La mia ipotesi è che non sia il più breve possibile, ma sono abbastanza contento perché la mia versione iniziale era di oltre 40 byte. modifica: avevo ragione, Luis ha trovato un altro byte da spremere!

,iZy]	# do twice: read input and find the size of each dimension
vX>	# find the maximum along each dimension
XKx	# save this into clipboard K and delete from stack. Stack is now empty.
,	# do twice:
 @G	# push the input at index i where i=0,1.
	# MATL indexes modularly, so 0 corresponds to the second input
 K:	# push the range 1...K[1]
 KP:	# push the range 1...K[2]
 3$)	# use 3-input ) function, which uses modular indexing
	# to expand the rows and columns to the appropriate broadcasted size
]	# end of loop
+	# sum the now appropriately-sized matrices and implicitly display

aspetta Luis Mendo a giocare a golf con altri 5 byte ;-)
Giuseppe,

MrGreen Il mio programma per i casi di test aveva 26 byte, ben fatto! Un uso piacevole :con input vettoriale
Luis Mendo,

4

Python 3 , 127 126 125 byte

golfato un byte cambiando sum(m)inm+n

Un altro byte grazie a @Jonathan Frech

lambda y:[[m+n for n,m,j in Z(l)]for*l,i in Z(y)]
from itertools import*
Z=lambda y:zip(*map(cycle,y),range(max(map(len,y))))

Accetta input come un elenco di due matrici bidimensionali.

  • Il Zlambda prende due array come input e restituisce un iteratore ottenendo un indice e fuse valori da entrambe le matrici, finché l'indice raggiunge lunghezza più grande dell'array. La variabile indice non mi è utile e mi costa byte, ma non so come farne a meno ... ( correlato )
  • La lambda principale prende appena le matrici di input e chiama Zle matrici esterne e interne. I valori più interni vengono sommati.

Provalo online!

Usare itertools.cycleè un po 'come imbrogliare, ma penso di essere stato abbastanza punito dalla pura lunghezza della dichiarazione di importazione :)

Sono sicuro che questo potrebbe essere giocato a golf un po 'di più, soprattutto il metodo di iterazione che le foglie questi inutili ie jvariabili. Le sarei grato per qualsiasi consiglio su come giocare a golf, probabilmente mi manca qualcosa di ovvio.


Potresti scambiare i tuoi zipargomenti, invertire fil compito di comprensione e quindi rimuovere uno spazio ( for i,*l-> for*l,i)? ( 125 byte )?
Jonathan Frech,

Un altro byte, grazie! Aggiornerò il mio post.
etene,

3

JavaScript (ES6), 131 byte

Non è lo strumento giusto per il lavoro, e probabilmente neanche l'approccio giusto. Vabbè ... ¯ \ _ (ツ) _ / ¯

a=>b=>(g=(a,b,c)=>[...Array((a[b[L='length']]?a:b)[L])].map(c))(a,b,(_,y)=>g(a[0],b[0],(_,x)=>(h=a=>a[y%a[L]][x%a[0][L]])(a)+h(b)))

Provalo online!

Come?

La funzione helper g () crea un array grande quanto l'array di input più grande ( a o b ) e invoca la funzione di callback c su di esso:

g = (a, b, c) =>
  [...Array(
    (a[b[L = 'length']] ? a : b)[L]
  )].map(c)

La funzione helper h () legge l'array 2D a at (x, y) con trasmissione modulare:

h = a => a[y % a[L]][x % a[0][L]]

Il codice principale ora si legge semplicemente come:

a => b =>
  g(a, b, (_, y) =>
    g(a[0], b[0], (_, x) =>
      h(a) + h(b)
    )
  )

Versione ricorsiva, 134 byte

a=>b=>(R=[],g=x=>a[y]||b[y]?a[0][x]+1|b[0][x]+1?g(x+1,(R[y]=R[y]||[])[x]=(h=a=>a[y%a.length][x%a[0].length])(a)+h(b)):g(+!++y):R)(y=0)

Provalo online!


3

05AB1E , 15 byte

2FεIζg∍ø]øεø¨}O

Provalo online!


Vecchia versione, 25 byte

é`DŠg∍)Σнg}`DŠнgδ∍€˜)ø€øO

Provalo online!

Spiegazione

15-byter:

2FεIζg∍ø] øεø¨} O - Programma completo. Accetta input come elenco 3D [A, B] da STDIN.
2F - Applicare due volte:
  ε - Per ognuno in [A, B]:
   Iζ - Traspone l'ingresso (riempiendo gli spazi con spazi).
     g - Lunghezza (recupera il numero di righe).
      ∍ - Estendi l'elemento corrente (A o B) alla lunghezza necessaria.
       ø - Transpose.
        ] - Chiudi tutti i loop.
         ø - Trasponi di nuovo.
          ε - Per ogni riga in ^ (colonna del risultato dei loop):
           ø - Traspone la colonna.
            ¨} - Rimuovi l'ultimo elemento e chiudi il map-loop.
              O - Somma.

25-byter:

é`DŠg∍) Σнg} `DŠнgδ∍ € ˜) ø € øO - Programma completo. Accetta input come elenco 3D da STDIN.
é - Ordina l'elenco per lunghezza.
 `D - Scarica i contenuti separatamente nello stack, duplica il ToS.
   Š: esegue uno scambio triplo. a, b, c -> c, a, b.
    g - Ottieni la lunghezza del ToS.
     ∍ - Estendi l'elenco più breve (in altezza) di conseguenza.
      ) Σ} - Avvolgi l'intero stack in un elenco e ordinalo per:
        нg - La lunghezza del suo primo oggetto.
           `DŠ - Come sopra.
              нg - La lunghezza del primo elemento.
                δ∍ € ˜ - Estendi l'elenco più breve (in larghezza) di conseguenza. 
                    ) ø - Avvolgere la pila in un elenco e trasporla (zip).
                      € ø - Quindi zip ogni elenco.
                        O: applica la somma vettorializzata.

3

R , 136 104 103 95 93 byte

Scivolò per ben 33 35 byte seguendo il consiglio di Giuseppe. Gestito per ottenere meno di 100 byte utilizzando un operatore come nome di una funzione. Vedi la cronologia per un codice più leggibile.

function(x,y,d=pmax(dim(x),dim(y)))y/d[2]/d[1]+x/d[2]/d[1]
"/"=function(x,j)apply(x,1,rep,,j)

Provalo online!


Bello! Ho golfato fino a 104 byte ma usando applyed rep.lenè quello che avevo considerato, anche se non ero riuscito a codificarlo da solo.
Giuseppe,

@Giuseppe Grazie! Tuttavia, la versione 104 non fornisce l'output previsto.
JayCe,

1
Uffa, continuo a trascinarti fuori strada! questo dovrebbe funzionare
Giuseppe,

1
@Giuseppe Adoro l'uso di dim, molto più pulito e apre le porte a una generalizzazione multidimensionale con chiamate ricorsive ar
JayCe

Ho provato a usare quello outer(x,y,"+")che contiene tutte le somme giuste e in modo chiaro. Non riesco a capire come estrarli in modo efficiente.
ngm,


2

05AB1E , 18 byte

éR`UvXNèy‚é`©g∍®+ˆ

Provalo online!

Spiegazione

éR                  # sort by length, descending
  `U                # store the shorter list in X
    v               # for each list y, index N in the longer list
     XNè            # get the nth element of the shorter list
        y‚é         # pair with y and sort by length
           `©g∍     # repeat the shorter list to the same length as the longer
               ®+   # elementwise addition of the lists
                 ˆ  # add to global list
                    # implicitly print global list

2

Pyth, 24 byte

KeSmlhdQmm+Fm@@bdkQKeSlM

Provalo qui

Spiegazione

KeSmlhdQmm+Fm@@bdkQKeSlM
                    eSlMQ  Get the maximum length of (implicit) input...
KeSmlhdQ           K       ... and the maximum row length.
        mm                 For each 2d index ...
          +Fm@@bdkQ        ... get the sum of the appropriate elements.

2

Java 8, 172 byte

A->B->{int m=A.length,o=A[0].length,d=B.length,u=B[0].length,l=m>d?m:d,a=o>u?o:u,r[][]=new int[l][a],$;for(;l-->0;)for($=a;$-->0;)r[l][$]=A[l%m][$%o]+B[l%d][$%u];return r;}

Provalo online.

Spiegazione:

A->B->{                   // Method with integer-matrix as both parameters and return-type
  int m=A.length,         //  Rows of `A`                        (we got an     M)
      o=A[0].length,      //  Columns of `A`                     (we got an     O)
      d=B.length,         //  Rows of `B`                        (we got a      D)
      u=B[0].length,      //  Columns of `B`                     (we got a      U)
      l=m>d?m:d,          //  Maximum of both rows               (we got an     L)
      a=o>u?o:u,          //  Maximum of both columns            (we got an     A)
      r[][]=new int[l][a],//  Result-matrix of size `l` by `a`   (and we got an R)
      $;                  //  Temp integer                       (which $pells? ;P)
  for(;l-->0;)            //  Loop over the rows
    for($=a;$-->0;)       //   Inner loop over the columns
      r[l][$]=            //    Set the current cell in the result-matrix to:
        A[l%m][$%o]       //     The value at {`l` modulo-`m`, `$` modulo-`o`} in `A`
        +B[l%d][$%u];     //     Plus the value at {`l` modulo-`d`, `$` modulo-`u`} in `B`
  return r;}              //  Return the result matrix


2

Python 2 , 124 116 byte

l=len
A,B=sorted(input(),key=l)
A*=l(B)
for i in eval(`zip(A,B)`):a,b=sorted(i,key=l);a*=l(b);print map(sum,zip(*i))

Provalo online!

Spiegazione:

Prende un elenco di due elenchi 2D come input.

l=len
A,B=sorted(input(),key=l)         # Sort inputed lists by length
A*=l(B)                           # Extend shorter list
for i in eval(`zip(A,B)`):        # Zip and remove copied references
  a,b=sorted(i,key=l)             # Sort lists in each pair (keep references)
  a*=l(b)                         # Extend shorter list
  print map(sum,zip(*i))          # Zip and sum

Ho preso idee da entrambe le nostre soluzioni e sono sceso a 105 byte . Ho dovuto usare Python 2, però, e ho ottenuto il trucco della moltiplicazione dal tuo codice, quindi non sarebbe giusto aggiornare la mia risposta :)
etene,

1
@etene Dovresti pubblicarlo, è un'ottima soluzione!
Dead Possum

Dannazione, errori piuttosto stupidi da parte mia, grazie (di nuovo)!
etene,

1
@etene Appena notato, questa soluzione ha avuto problemi con 2 e 6 casi di test. È necessario rimuovere i riferimenti copiati
Dead Possum

1
@etene Torna a 105 byte : C
Dead Possum

2

Python 2 , 101 97 105 byte

Modifica: grazie (di nuovo!) A Dead Possum per aver salvato 4 byte

Modifica 2: perso 8 byte, alcuni casi di test non stavano superando

Un mix tra la precedente soluzione di Dead Possum (grazie a lui!) E la mia soluzione Python 3 .

lambda y:[map(sum,P(i))for i in P(y)]
def P(y):y=sorted(y,key=len);y[0]*=len(y[1]);return eval(`zip(*y)`)

Provalo online!

Stesso input della mia soluzione Python 3 (una coppia di elenchi bidimensionali).

Codice commentato:

# Iterate over the nested lists, resized & joined by P(),
# and sum the inner joined items
lambda y:[map(sum,P(i))for i in P(y)]
def P(y):
 y=sorted(y,key=len)  # Sort the two input lists by length
 y[0]*=len(y[1])      # Multiply the smallest one by the biggest one's length
                      # (The smallest list is now the previously largest one)
 return eval(`zip(*y)`)  # Return paired list elements up to the smallest list's length

1

Julia 0.6 , 85 83 byte

M\N=(((r,c),(s,d))=size.((M,N));repmat(M,s,d)+repmat(N,r,c))[1:max(r,s),1:max(c,d)]

Provalo online!

(Sostituisci con \grazie a Jo King )

Funziona ripetendo ciascuna matrice in senso orizzontale e verticale in modo che abbiano entrambe le stesse dimensioni (prodotto delle dimensioni della riga x prodotto delle dimensioni della colonna), aggiungendo quelle in alto ed estraendo la regione corretta da quella. (Gli input di vettore di riga o input di vettore di colonna richiedono il reshapecast di una chiamata come array bidimensionali, che presumo vada bene poiché la domanda specifica "Aggiunta di implementazioni per array bidimensionali" e "Input e output possono essere presi da qualsiasi mezzi ragionevoli. Il loro formato è flessibile come al solito. ")

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.