Radiodifusão modular

24

Esse desafio está relacionado a alguns dos recursos da linguagem MATL, como parte do evento de linguagem do mês de maio de 2018 .


Introdução

No MATL, muitas funções de duas entradas funcionam em elementos com transmissão . Isso significa o seguinte:

  • Em termos de elementos (ou vetorizados ): a função aceita como entradas duas matrizes com tamanhos correspondentes. A operação definida pela função é aplicada a cada par de entradas correspondentes. Por exemplo, usando a notação pós-correção:

    [2 4 6] [10 20 30] +
    

    a saída

    [12 24 36]
    

    Isso também funciona com matrizes multidimensionais. A notação [1 2 3; 4 5 6]representa a matriz 2× 3(matriz)

    1 2 3
    4 5 6
    

    que tem tamanho 2ao longo da primeira dimensão (vertical) e 3ao longo da segunda (horizontal). Então por exemplo

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

    [20 80 180; 120 300 560]
    
  • Transmissão ou ( expansão singleton ): as duas matrizes de entrada não têm tamanhos correspondentes, mas em cada dimensão não correspondente, uma das matrizes possui tamanho 1. Essa matriz é replicada implicitamente ao longo das outras dimensões para fazer corresponder os tamanhos; e então a operação é aplicada elemento a elemento como acima. Por exemplo, considere duas matrizes de entrada com os tamanhos 1× 2e 3× 1:

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

    Graças à transmissão, isso é equivalente a

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

    e assim

    [10 20; 5 10; 2 4]
    

    Da mesma forma, com tamanhos 3× 2e 3× 1(a transmissão agora atua apenas na segunda dimensão),

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

    [19 18; 27 26; 35 34]
    

    O número de dimensões pode até ser diferente. Por exemplo, entradas com tamanhos 3 × 2 e 3 × 1 × 5 são compatíveis e fornecem um resultado 3 × 2 × 5. De fato, o tamanho 3 × 2 é o mesmo que 3 × 2 × 1 (existem arbitrariamente muitas dimensões singleton à direita implícitas).

    Por outro lado, um par de 2× 2e 3× 1matrizes daria um erro, porque os tamanhos ao longo da primeira dimensão são 2e 3: eles não são iguais e nenhum deles é 1.

Definição de radiodifusão modular

A transmissão modular é uma generalização da transmissão que funciona mesmo que nenhum dos tamanhos não correspondentes 1. Considere por exemplo o seguinte 2× 2e 3× 1matrizes como entradas da função +:

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

A regra é a seguinte: para cada dimensão, a matriz menor ao longo dessa dimensão é replicada modularmente (ciclicamente) para corresponder ao tamanho da outra matriz. Isso tornaria o equivalente acima

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

com o resultado

[12 14; 26 28; 32 34]

Como um segundo exemplo,

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

produziria

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

Em geral, entradas com tamanhos a× be c× dresultam em tamanho max(a,b)× max(c,d).

O desafio

Implemente adição para matrizes bidimensionais com transmissão modular, conforme definido acima.

As matrizes serão retangulares (sem irregularidades), conterão apenas números inteiros não negativos e terão tamanho pelo menos1 em cada dimensão.

Regras adicionais:

Casos de teste

O seguinte é usado ;como separador de linhas (como nos exemplos acima). Cada caso de teste mostra as duas entradas e depois a saída.

[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]
Luis Mendo
fonte
"Implementar adição para matrizes bidimensionais" - há casos de teste unidimensionais.
Jonathan Allan
Podemos supor que não recebemos matrizes irregulares? (parece)
Jonathan Allan #
11
@JonathanAllan Desculpe por não ser claro. Sim, você pode assumir que não há matrizes irregulares. Eles serão matrizes retangulares. Os "unidimensionais" devem ser considerados bidimensionais com tamanho 1× n(como [1 2 3]) ou n× 1(como [1; 2; 3]))
Luis Mendo
A transmissão que você descreve parece mais limitada que a transmissão MATLAB ou NumPy; na sua descrição, as entradas devem ter o mesmo número de dimensões, uma restrição que não está presente no MATLAB ou NumPy. Isso é uma restrição MATL ou uma simplificação para os propósitos do desafio (já que o desafio é limitado à entrada 2D)?
User2357112 suporta Monica
@ user2357112 Sim, foi uma simplificação na descrição. A transmissão do MATL é a mesma do MATLAB: você pode ter entradas 3 × 2 e 3 × 1 × 5 e obter um resultado 3 × 2 × 5. Na verdade, 3 × 2 é equivalente a 3 × 2 × 1 (dimensões finais implícitas). Eu acho que é semelhante no Numpy (mas com dimensões principais). Esclareci isso na introdução
Luis Mendo

Respostas:

4

Gelatina , 10 bytes

ṁ€ZL$Z€Ɗ⁺S

Pega um par de matrizes (duas matrizes de linhas) como entrada e retorna uma matriz.

Experimente online!

Como funciona

ṁ€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.
Dennis
fonte
11
É claro ... Eu vejo todas essas linguagens de golfe como algo compatível em termos de bytes necessários para um desafio (Jelly, 05AB1E, Pyth, APL, etc.) A maioria das respostas atuais tem cerca de 20 bytes e aqui vem o Assistente Dennis. com uma resposta pela metade disso ;; ) Muito engraçado quando memes e verdade são a mesma coisa: " Ninguém supera o Dennis! .. "
Kevin Cruijssen
11
@KevinCruijssen APL não é uma linguagem de golfe.
Adám
11
@ Adám eu sei, eu sei. Mas ainda é muito curto (apesar de ter sido desenvolvido pela primeira vez na década de 1960). Talvez eu devesse ter falado línguas curtas em vez de línguas de golfe. Ah, bem ..
Kevin Cruijssen
5

Carvão , 25 23 bytes

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

Experimente online! Link é a versão detalhada do código. Recebe a entrada como uma matriz tridimensional. Explicação:

Aθ

Coloque tudo.

    θ                   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
Neil
fonte
: P (ainda é mais longo> _>)
somente ASCII
5

MATL , 25 24 bytes

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

Experimente online!

Finalmente! Levou apenas uma semana para que o desafio inspirado no idioma do mês fosse respondido pelo idioma do mês!

Meu palpite é que não é tão curto quanto possível, mas estou feliz o suficiente porque minha versão inicial tinha mais de 40 bytes. editar: eu estava certo, Luis encontrou outro byte para espremer!

,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
Giuseppe
fonte
espera por Luis Mendo para golf fora mais 5 bytes ;-)
Giuseppe
:-D Meu programa para os casos de teste tinha 26 bytes, muito bem! Uso legal da parte :com a entrada vector
Luis Mendo
4

Python 3 , 127 126 125 bytes

jogou um byte mudando sum(m)param+n

Mais um byte graças 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))))

Recebe a entrada como uma lista de duas matrizes bidimensionais.

  • O Zlambda recebe duas matrizes como entrada e retorna um iterador produzindo um índice e valores mesclados de ambas as matrizes, até que o índice atinja o maior comprimento da matriz. A variável index não é útil para mim e me custa bytes, mas não sei como ficar sem ela ... ( relacionada )
  • O lambda principal apenas pega as matrizes de entrada e chama Zas matrizes externas e internas. Os valores mais internos são adicionados juntos.

Experimente online!

Usar itertools.cycleparece um pouco trapaceiro, mas acho que já fui punido o suficiente pelo tamanho da declaração de importação :)

Tenho certeza de que isso poderia ser um pouco mais praticado, especialmente o método de iteração que deixa essas variáveis ie inúteis j. Eu ficaria grato por qualquer dica sobre como jogar isso, provavelmente estou perdendo algo óbvio.

eteno
fonte
Você poderia trocar zipos argumentos de sua pessoa, reverter fa tarefa de compreensão e assim remover um espaço ( for i,*l-> for*l,i)? ( 125 bytes )?
Jonathan Frech
Mais um byte, obrigado! Vou atualizar minha postagem.
Etene
3

JavaScript (ES6), 131 bytes

Não é a ferramenta certa para o trabalho, e provavelmente também não é a abordagem certa. Oh bem ... ¯ \ _ (ツ) _ / ¯

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)))

Experimente online!

Quão?

A função auxiliar g () cria uma matriz do tamanho da maior matriz de entrada ( a ou b ) e chama a função de retorno de chamada c sobre ela:

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

A função auxiliar h () lê o array 2D a em (x, y) com transmissão modular:

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

O código principal agora é simplesmente lido como:

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

Versão recursiva, 134 bytes

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)

Experimente online!

Arnauld
fonte
3

05AB1E , 15 bytes

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

Experimente online!


Versão antiga, 25 bytes

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

Experimente online!

Explicação

15 bytes:

2FεIζg∍ø] øεø¨} O - Programa completo. Recebe a entrada como uma lista 3D [A, B] de STDIN.
2F - Aplicar duas vezes:
  ε - Para cada um em [A, B]:
   Iζ - Transponha a entrada (preenchendo espaços com espaços).
     g - Comprimento (recupere o número de linhas).
      Ext - Estenda o item atual (A ou B) até o comprimento necessário.
       ø - Transpor.
        ] - Feche todos os loops.
         ø - Transponha novamente.
          ε - Para cada linha em ^ (coluna do resultado dos loops):
           ø - Transponha a coluna.
            ¨} - Remova o último elemento e feche o loop do mapa.
              O - soma.

25 bytes:

é`DŠg∍) }нg} `DŠнgδ∍ € ˜) ø € øO - Programa completo. Recebe a entrada como uma lista 3D do STDIN.
é - Classifique a lista por comprimento.
 `D - Despeje o conteúdo separadamente na pilha, duplique os ToS.
   Š - Realize uma troca tripla. a, b, c -> c, a, b.
    g - Obtenha o comprimento dos ToS.
     ∍ - Estenda a lista mais curta (em altura) de acordo.
      ) -} - Coloque a pilha inteira em uma lista e classifique-a por:
        нg - O comprimento do seu primeiro item.
           `DŠ - O mesmo que acima.
              í - O comprimento do primeiro elemento.
                δ∍ € ˜ - Estenda a lista mais curta (em largura) de acordo. 
                    ) ø - Coloque a pilha em uma lista e transponha (zip).
                      € ø - Em seguida, zip cada lista.
                        O - Aplicar somatório vetorizado.
Mr. Xcoder
fonte
3

R , 136 104 103 95 93 bytes

Jogou golfe com 33 35 bytes, seguindo o conselho de Giuseppe. Conseguiu obter menos de 100 bytes usando um operador como um nome de função. Veja o histórico para obter um código mais legível.

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)

Experimente online!

JayCe
fonte
Agradável! Joguei isso até 104 bytes, mas usando applye rep.lené o que eu havia considerado, embora não tivesse conseguido codificá-lo.
Giuseppe
@Giuseppe Thanks! A versão 104 não fornece a saída esperada.
JayCe
11
Ugh, eu continuo te desviando! este deve funcionar #
317 Giuseppe
11
@Giuseppe Adoro o uso de dim , muito mais limpo e abre a porta para uma generalização multi-dimensional com chamadas recursivas parar
Jayce
Eu tenho tentado usar outer(x,y,"+")que contém todas as somas certas, e em um padrão claro. Não consigo descobrir como extraí-los com eficiência.
ngm
2

05AB1E , 18 bytes

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

Experimente online!

Explicação

é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
Emigna
fonte
2

Pitão, 24 bytes

KeSmlhdQmm+Fm@@bdkQKeSlM

Experimente aqui

Explicação

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.

fonte
2

Java 8, 172 bytes

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

Experimente online.

Explicação:

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
Kevin Cruijssen
fonte
2

Python 2 , 124 116 bytes

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))

Experimente online!

Explicação:

Leva a lista de duas listas 2-d como entrada.

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
Gambá morto
fonte
Peguei idéias de ambas as soluções e reduzi-me a 105 bytes . Eu tive que usar Python 2, porém, e eu tenho o truque multiplicação do seu código, por isso não me sentiria bem para atualizar a minha resposta :)
eteno
11
@ etene Você deve publicá-lo, é uma boa solução!
Gambá morto
Malditos erros estúpidos da minha parte, obrigado (de novo)!
Eteno # 4/18
11
@ etene Acabei de notar que esta solução teve problemas com 2 e 6 casos de teste. Necessidade de remover as referências copiados
Morto Possum
11
@etene Voltar para 105 bytes : C
Gambá morto
2

Python 2 , 101 97 105 bytes

Edit: Obrigado (novamente!) Ao Dead Possum por salvar 4 bytes

Edit 2: perdeu 8 bytes, alguns casos de teste não estavam passando

Uma mistura entre a solução anterior do Dead Possum (graças a ele!) E minha própria solução 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)`)

Experimente online!

A mesma entrada da minha solução Python 3 (um par de listas bidimensionais).

Código comentado:

# 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
eteno
fonte
1

Julia 0.6 , 85 83 bytes

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

Experimente online!

(Substitua por \agradecimentos a Jo King )

Funciona repetindo cada matriz horizontal e verticalmente para que ambos tenham o mesmo tamanho (produto de tamanhos de linha x produto de tamanhos de coluna), somando-os e extraindo a região correta a partir disso. (As entradas de vetor de linha ou de vetor de coluna precisam que uma reshapechamada seja convertida como matrizes bidimensionais, o que suponho que seja bom, pois a pergunta especifica "Implementar adição para matrizes bidimensionais" e "Entrada e saída podem ser atendidas por qualquer razoáveis. Seu formato é flexível como de costume. ")

sundar - Restabelecer Monica
fonte