Trova la matrice secondaria con la media più piccola


21

Ti viene data una matrice n-per-m di numeri interi, dove n, m> 3 . Il tuo compito è quello di trovare la matrice secondaria 3 per 3 che abbia la media più bassa e produrre questo valore.

Regole e chiarimenti:

  • I numeri interi saranno non negativi
  • Formato di input e output opzionale
  • L'output deve essere accurato fino ad almeno 2 punti decimali (se non è intero)
  • Le matrici devono essere costituite da righe e colonne consecutive

Casi test:

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

Questo è quindi vince il codice più corto in ogni lingua. Incoraggio le persone a pubblicare risposte in lingue già utilizzate, anche se non sono più brevi della prima.


Sarebbe anche interessante avere una sfida con file e colonne non necessariamente contigue
Luis Mendo,

No, vai avanti tu stesso :-)
Luis Mendo,

Intendi numeri interi in senso matematico o di tipo di dati, cioè possiamo prendere una matrice di float integrali?
Dennis,

Senso matematico. È una cosa che ho imparato qui, è che puoi fare ipotesi sui tipi di dati in varie lingue ...
Stewie Griffin,

Dolce, che salva un byte. Grazie per il chiarimento.
Dennis,

Risposte:



11

Gelatina , 11 9 byte

+3\⁺€F÷9Ṃ

Salvato 2 byte grazie a @ Dennis .

Provalo online!

Spiegazione

+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

1
Oh,> _ <ovviamente: D
Jonathan Allan

Sarei interessato a una versione ungolfed di gelatina, dal momento che ha così tante funzioni utili.
J Atkin,

1
+3\⁺€F÷9Ṃsalva un paio di byte.
Dennis,

@Dennis Wow, è davvero l'elaborazione +3\prima e il duplicato come +3\€? Non mi aspettavo che ciò accadesse
miglia

1
Il parser è essenzialmente basato su stack; \apre 3e +invia il collegamento rapido +3\, apre il collegamento rapido e invia due copie, quindi apre la copia più in alto e invia una versione di mappatura.
Dennis,


8

MATL , 13 9 byte

3thYCYmX<

La risposta di Port of @ rahnema1 .

Provalo online!

Come funziona

Considera l'input

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

come esempio.

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]

7

Mathematica, 37 35 byte

Grazie @MartinEnder per 2 byte!

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

Spiegazione

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

Molto molto lucido!
Greg Martin,

5

Python 2 , 93 81 80 79 byte

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

Provalo online!

Come funziona

f è una funzione ricorsiva che accetta un elenco di tuple (o qualsiasi altro iterabile 2D indicizzabile che rappresenta una matrice M ) e calcola ricorsivamente il minimo della media della sottomatrice 3 × 3 nell'angolo in alto a sinistra e f applicato ricorsivamente a M senza la sua prima riga e M senza la sua prima colonna.

f(M) fa quanto segue.

  • Se M ha meno di tre righe, M[2:]è un elenco vuoto, che f restituisce.

    Si noti che, poiché n> 3 nella prima esecuzione, l'iniziale non può restituire un elenco vuoto.

  • Se M ha tre o più righe, M[2:]è non vuoto e quindi veritiero, quindi il codice a destra di andviene eseguito, restituendo il minimo dei tre seguenti valori.

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

    M[:3]produce le prime tre righe di M , zip(*...)traspone righe e colonne (producendo un elenco di tuple), sum(...,())concatena tutte le tuple (funziona perché +è concatenazione) e sum(...)/9calcola la media dell'elenco risultante di nove numeri interi.

    f(M[1:])

    applica ricorsivamente f a M con la sua prima riga rimossa.

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

    traspone righe e colonne, rimuove la prima riga del risultato (quindi la prima colonna di M e applica ricorsivamente f al risultato.

Nota che il livello precedentemente rimosso in una chiamata ricorsiva sarà sempre una riga, quindi testare se M ha abbastanza righe sarà sempre sufficiente.

Infine, ci si può aspettare che il ritorno di alcune chiamate ricorsive []sia un problema. Tuttavia, in Python 2 , ogni volta che n è un numero e A è un iterabile, il confronto n < Arestituisce True , quindi il calcolo del minimo di uno o più numeri e uno o più iterabili restituiranno sempre il numero più basso.


3

J , 21 byte

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

Provalo online!

Il modo corretto di operare sui sottoarray in J è usare la terza ( _3) forma di taglio ;.dove si x (u;._3) yintende applicare il verbo usu ogni sottoarray completo di dimensione xdell'array y. Una soluzione che utilizza richiede solo 1 byte in più ma sarà molto più efficiente su array più grandi.

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

Provalo online!

Spiegazione

[:<./@,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

1
Mi piace come []sembrano abbinati, ma in realtà non lo sono.
Lynn,

1
@Lynn Aspetta un secondo, non è vero. J dovrebbe distrarre gli spettatori con più parentesi sbilanciate. Avrei dovuto usare un [o |:)
miglia il

2

Gelatina , 18 byte

Perso il trucco, usato da miglia nella loro risposta , di usare una riduzione cumulativa n-saggia dell'aggiunta - l'intera prima riga può essere sostituita con +3\11.

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

Provalo online!

Attraversa tutti gli elenchi contigui contigui, i filtri per mantenere solo quelli di lunghezza 3 e somme (che vettorializza) quindi si ripete per ogni elenco risultante, per ottenere le somme di tutti i 3 per 3 sotto-matrici e infine li appiattisce in un elenco, prende il minimo e divide per 9 (il numero di elementi che compongono questa somma minima).


Mi piace l'idea delle liste di filtro. Utile se la dimensione dell'elenco secondario dipende da un valore calcolato.
miglia

2

Pyth, 19 byte

chSsMsMs.:R3C.:R3Q9

Un programma che accetta l'inserimento di un elenco di elenchi e stampa il risultato.

Suite di test

Come funziona

[Spiegazione che verrà dopo]



1

Python 2, 96 byte

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.

Casi di prova su Repl.it

Una funzione senza nome che prende un elenco di elenchi, a- le righe della matrice.

La funzione helper hcomprime tre sezioni adiacenti e mappa la funzione somma attraverso la trasposizione zip(*s)di ciascuna. Ciò comporta la somma di tutte le alte tre sezioni di singole colonne.

La funzione senza nome chiama la funzione di supporto, traspone e richiama nuovamente la funzione di supporto sul risultato, quindi trova il minimo di ciascuno e il minimo del risultato, che poi divide 9.per ottenere la media.


1

JavaScript (ES6), 107 98 96 byte

Una funzione che calcola le somme delle terzine sulle righe e poi si chiama a fare la stessa cosa sulle colonne, tenendo traccia del valore minimo 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 è un po 'prolisso per quel tipo di cose e manca un zip()metodo nativo . Mi ci è voluto molto tempo per salvare solo una dozzina di byte con un approccio più ingenuo. (Tuttavia, esiste probabilmente un metodo più breve.)

Versione non ricorsiva, 103 byte

Salvato 2 byte con l'aiuto di 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

Casi test


Sono un po 'interessato al tuo cosiddetto approccio ingenuo, dal momento che il meglio che potevo fare con un approccio ragionevolmente puro era 113 byte:(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 Penso che sia stato qualcosa di simile 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, anche se penso che il mio primo tentativo sia stato in realtà più grande di così.
Arnauld,

Bello, anche se sono stato in grado di radere fuori un 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. Ciò consente di salvare un altro byte conm=>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 byte

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

Provalo online!

Spiegazione

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

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.