Encontre a submatriz com a menor média

21

Você recebe uma matriz n por m de números inteiros, onde n, m> 3 . Sua tarefa é encontrar a sub-matriz 3 por 3 que tem a média mais baixa e gerar esse valor.

Regras e esclarecimentos:

  • Os números inteiros não serão negativos
  • Formato opcional de entrada e saída
  • A saída deve ser precisa até pelo menos 2 pontos decimais (se não for um número inteiro)
  • As submatrizes devem ser compostas de linhas e colunas consecutivas

Casos de teste:

35    1    6   26   19   24
 3   32    7   21   23   25
31    9    2   22   27   20
 8   28   33   17   10   15
30    5   34   12   14   16
 4   36   29   13   18   11 

Minimum mean: 14

100    65     2    93
  3    11    31    89
 93    15    95    65
 77    96    72    34

Minimum mean: 46.111

1   1   1   1   1   1   1   1
1   1   1   1   1   1   1   1
1   1   1   1   1   1   1   1
1   1   1   1   1   1   1   1

Minimum mean: 1

4   0   0   5   4
4   5   8   4   1
1   4   9   3   1
0   0   1   3   9
0   3   2   4   8
4   9   5   9   6
1   8   7   2   7
2   1   3   7   9

Minimum mean: 2.2222

Este é o portanto o código mais curto em cada idioma vence. Encorajo as pessoas a postar respostas em idiomas que já são usados, mesmo que não sejam mais curtos que o primeiro.

Stewie Griffin
fonte
Também seria interessante ter um desafio com linhas e colunas não necessariamente contíguas
Luis Mendo
Não, vá em frente :-)
Luis Mendo
Você quer dizer números inteiros no sentido matemático ou do tipo de dados, ou seja, podemos obter uma matriz de flutuadores integrais?
Dennis
Senso matemático. É uma coisa que eu aprendi aqui, é que você pode fazer suposições sobre tipos de dados em vários idiomas ...
Stewie Griffin
Doce, isso economiza um byte. Agradeço por ter esclarecido.
Dennis19 /

Respostas:

11

Geléia , 11 9 bytes

+3\⁺€F÷9Ṃ

Economizou 2 bytes graças a @ Dennis .

Experimente online!

Explicação

+3\⁺€F÷9Ṃ  Main link. Input: 2d matrix
+3\        Reduce overlapping sublists of size 3 by addition
   ⁺€      Repeat previous except over each row
     F     Flatten
      ÷9   Divide by 9
        Ṃ  Minimum
milhas
fonte
11
Ah,> _ <é claro: D
Jonathan Allan
Eu estaria interessado em uma versão ungolfed de geléia, uma vez que tem tantas funções úteis.
precisa
11
+3\⁺€F÷9Ṃsalva alguns bytes.
Dennis19 /
@ Dennis Wow, isso realmente processa +3\primeiro e o duplicado como +3\€? Não esperava que isso acontecesse
milhas
11
O analisador é essencialmente baseado em pilha; \abre 3e +empurra o link rápido +3\, abre o link rápido e empurra duas cópias, em seguida, abre a cópia superior e empurra uma versão de mapeamento.
Dennis
8

Oitava, 38 bytes

@(M)min(conv2(M,ones(3)/9,'valid')(:))
Rainer P.
fonte
8

MATL , 13 9 bytes

3thYCYmX<

Porto da resposta de @ rahnema1 .

Experimente online!

Como funciona

Considere entrada

[100 65  2 93;
   3 11 31 89;
  93 15 95 65;
  77 96 72 34]

como um exemplo.

3th   % Push [3 3]
      % STACK: [3 3]
YC    % Input matrix implicitly. Convert 3x3 sliding blocks into columns
      % STACK: [100   3  65  11;
                  3  93  11  15;
                 93  77  15  96;
                 65  11   2  31;
                 11  15  31  95;
                 15  96  95  72;
                  2  31  93  89;
                 31  95  89  65;
                 95  72  65  34]
Ym    % Mean of each column
      % STACK: [46.1111 54.7778 51.7778 56.4444]
X<    % Minimum of vector. Display implicitly
      % STACK: [46.1111]
Luis Mendo
fonte
7

Mathematica, 37 35 bytes

Obrigado @MartinEnder por 2 bytes!

Min@BlockMap[Mean@*Mean,#,{3,3},1]&

Explicação

Min@BlockMap[Mean@*Mean,#,{3,3},1]&
    BlockMap[                    ]&  (* BlockMap function *)
                        #            (* Divide the input *)
                          {3,3}      (* Into 3x3 matrices *)
                                1    (* With offset 1 *)
             Mean@*Mean              (* And apply the Mean function twice to
                                        each submatrix *)
Min                                  (* Find the minimum value *)
JungHwan Min
fonte
Muito, muito liso!
Greg Martin
5

Python 2 , 93 81 80 79 bytes

f=lambda M:M[2:]and min(sum(sum(zip(*M[:3])[:3],()))/9,f(M[1:]),f(zip(*M)[1:]))

Experimente online!

Como funciona

f é uma função recursiva que pega uma lista de tuplas (ou qualquer outra iterável 2D indexável que represente uma matriz M ) e calcula recursivamente o mínimo da média da submatriz 3 × 3 no canto superior esquerdo ef aplicada de forma recursiva a M sem sua primeira linha e M sem sua primeira coluna.

f(M) faz o seguinte.

  • Se M tiver menos de três linhas, M[2:]é uma lista vazia, que f retorna.

    Observe que, como n> 3 na primeira execução, a inicial não pode retornar uma lista vazia.

  • Se M tiver três linhas ou mais, M[2:]não estiver vazio e, portanto, verdadeiro, o código à direita andserá executado, retornando o mínimo dos três valores a seguir.

    min(sum(sum(zip(*M[:3])[:3],()))/9

    M[:3]gera as três primeiras linhas de M , zip(*...)transpõe linhas e colunas (produzindo uma lista de tuplas), sum(...,())concatena todas as tuplas (isso funciona porque +é concatenação) e sum(...)/9calcula a média da lista resultante de nove números inteiros.

    f(M[1:])

    aplica recursivamente f a M com sua primeira linha removida.

    f(zip(*M)[1:])

    transpõe linhas e colunas, remove a primeira linha do resultado (portanto, a primeira coluna de M e aplica-se recursivamente f ao resultado.

Observe que a camada removida anteriormente em uma chamada recursiva sempre será uma linha, portanto, testar se M tem linhas suficientes sempre será suficiente.

Finalmente, pode-se esperar que o retorno de algumas chamadas recursivas []seja um problema. No entanto, no Python 2 , sempre que n for um número e A for iterável, a comparação n < Aretornará True ; portanto, calcular o mínimo de um ou mais números e um ou mais iteráveis ​​sempre retornará o número mais baixo.

Dennis
fonte
3

J , 21 bytes

[:<./@,9%~3+/\3+/\"1]

Experimente online!

A maneira correta de operar em sub-matrizes em J é usar a terceira _3forma de corte ( ), ;.onde x (u;._3) ysignifica aplicar o verbo uem cada sub- xmatriz completa do tamanho da matriz y. Uma solução usando isso requer apenas mais 1 byte, mas será muito mais eficiente em matrizes maiores.

[:<./@,9%~3 3+/@,;._3]

Experimente online!

Explicação

[:<./@,9%~3+/\3+/\"1]  Input: 2d array M
                    ]  Identity. Get M
                  "1   For each row
              3  \       For each overlapping sublist of size 3
               +/          Reduce by addition
          3  \         For each overlapping 2d array of height 3
           +/            Reduce by addition
       9%~             Divide by 9
[:    ,                Flatten it
  <./@                 Reduce by minimum
milhas
fonte
11
Eu gosto da []aparência deles, mas na verdade não é.
Lynn
11
@ Lynn Espere um segundo, isso não está certo. J deve distrair os espectadores com vários colchetes desequilibrados. Deveria ter usado um [ou |:)
miles
2

Gelatina , 18 bytes

Perdeu o truque, usado por milhas em sua resposta , ao usar uma redução cumulativa n-wise de adição - toda a primeira linha pode ser substituída +3\por 11.

ẆµL=3µÐfS€
ÇÇ€FṂ÷9

Experimente online!

Atravessa todas as sublistas contíguas, filtra para manter apenas as de comprimento 3 e somas (que vetoriza) e depois repete para cada lista resultante, para obter as somas de todas as sub-matrizes 3 por 3 e, por fim, as nivela em uma lista, leva o mínimo e divide por 9 (o número de elementos que fazem essa soma mínima).

Jonathan Allan
fonte
Eu gosto da idéia de sublistas de filtragem. Útil se o tamanho da sub-lista dependesse de um valor calculado.
miles
2

Pitão, 19 bytes

chSsMsMs.:R3C.:R3Q9

Um programa que recebe entrada de uma lista de listas e imprime o resultado.

Suíte de teste

Como funciona

[Explicação que vem depois]

TheBikingViking
fonte
1

Python 3 , 111 103 bytes

lambda m,r=range:min(sum(sum(m[y+i][x:x+3])for i in r(3))/9for x in r(len(m[0])-3)for y in r(len(m)-3))

Experimente online!

ovs
fonte
1

Python 2, 96 bytes

h=lambda a:[map(sum,zip(*s))for s in zip(a,a[1:],a[2:])]
lambda a:min(map(min,h(zip(*h(a)))))/9.

Casos de teste em Repl.it

Uma função sem nome que faz uma lista de listas, a- as linhas da matriz.

A função auxiliar hpercorre três fatias adjacentes e mapeia a função de soma através da transposição zip(*s), de cada uma. Isso resulta na soma de todas as alturas de três fatias de colunas únicas.

A função sem nome chama a função auxiliar, transpõe e chama a função auxiliar novamente no resultado e, em seguida, encontra o mínimo de cada um e o mínimo do resultado, que ele divide 9.para produzir a média.

Jonathan Allan
fonte
1

JavaScript (ES6), 107 98 96 bytes

Uma função que calcula a soma de trigêmeos nas linhas e, em seguida, chama a si mesma a fazer o mesmo nas colunas, mantendo o controle do valor mínimo M.

f=m=>m.map((r,y)=>r.map((v,x)=>M=(z[x<<9|y]=v+=r[x+1]+r[x+2])<M?v:M),z=[M=1/0])&&m[1]?f([z]):M/9

JS é um pouco detalhado para esse tipo de coisa e não possui um zip()método nativo . Levei muito tempo para salvar apenas uma dúzia de bytes em uma abordagem mais ingênua. (No entanto, provavelmente existe um método mais curto.)

Versão não recursiva, 103 bytes

Economizou 2 bytes com a ajuda de Neil

m=>m.map((r,y)=>y>1?r.map((v,x)=>[..."12345678"].map(i=>v+=m[y-i%3][x+i/3|0])&&(M=v<M?v:M)):M=1/0)&&M/9

Casos de teste

Arnauld
fonte
Estou um pouco interessado na sua abordagem ingênua, já que o melhor que pude fazer com uma abordagem razoavelmente pura foi de 113 bytes: #(a,b=a.map(g=a=>a.slice(2).map((e,i)=>a[i]+a[i+1]+e)))=>eval(`Math.min(${b[0].map((_,i)=>g(b.map(a=>a[i])))})`)/9
Neil
@ Neil Eu acho que era algo próximo m=>m.map((r,y)=>r.map((v,x)=>[..."12345678"].map(i=>v+=(m[y+i/3|0]||[])[x+i%3])&&(M=v<M?v:M)),M=1/0)&&M/9, embora eu acho que minha primeira tentativa foi realmente maior do que isso.
Arnauld
Bom, embora eu era capaz de raspar um byte: m=>m.map((r,y)=>y>1&&r.map((v,x)=>[..."12345678"].map(i=>v+=m[y-i%3][x+i/3|0])&&(M=v<M?v:M)),M=1/0)&&M/9.
Neil
@Neil Cool. Isto permite salvar mais um byte comm=>m.map((r,y)=>y>1?r.map((v,x)=>[..."12345678"].map(i=>v+=m[y-i%3][x+i/3|0])&&(M=v<M?v:M)):M=1/0)&&M/9
Arnauld
1

05AB1E , 21 16 bytes

2FvyŒ3ùO})ø}˜9/W

Experimente online!

Explicação

2F         }       # 2 times do:
  v     }          # for each row in the matrix
   yŒ3ù            # get all sublists of size 3
       O           # reduce by addition
         )ø        # transpose matrix
            ˜      # flatten the matrix to a list
             9/    # divide each by 9
               W   # get the minimum
Emigna
fonte
1

Haskell , 87 bytes

import Data.List
t(a:b:c:d)=a+b+c:t(b:c:d);t _=[]
s=(/9).minimum.(t=<<).transpose.map t

Experimente online!

Roman Czyborra
fonte