Controlla se una matrice è una matrice di Toeplitz


11

Ti verrà dato un array bidimensionale e un numero e ti verrà chiesto di scoprire se la matrice data è Toeplitz o meno.

Formato di input:

Ti verrà data una funzione che prenderà la two-dimensionalmatrice come argomento.

Formato di output:

Ritorna 1dalla funzione se la matrice è Toeplitz , altrimenti ritorna -1.

vincoli:

3 < n,m < 10,000,000

dove nè il numero di righe mentre msarà il numero di colonne.

Esempio di test:

Sample Input :
4 
5
6 7 8 9 2
4 6 7 8 9
1 4 6 7 8
0 1 4 6 7 

Sample Output : 
1 

punteggio

Questo è , quindi vince la risposta più breve in byte.


8
Questa è una bella sfida, ma preferiamo qui i requisiti I / O lassisti. Suggerirei di consentire sia i programmi che le funzioni come impostazione predefinita . E consentire True / False o 1/0 come output, o forse solo due output distinti coerenti come sembra essere preferito per problemi di decisione.
xnor

15
Inoltre, una definizione di Toeplitz sarebbe buona, così come lo sarebbero più casi di test inclusi quelli non Toeplitz. Non sono sicuro di cosa intendi con l'aggiunta di codice.
xnor

5
Penso che tu debba ridurre il valore massimo di n, m . Altrimenti la parte principale di questa sfida è trovare un modo per elaborare una matrice da 1 terabyte.
Stewie Griffin,

1
Gli elementi della matrice saranno sempre numeri interi non negativi?
Martin Ender,

Risposte:


7

Mathematica, 42 byte

2Boole[#==ToeplitzMatrix[#&@@@#,#&@@#]]-1&

Mathematica non ha un built-in per verificare se qualcosa è una matrice di Toeplitz, ma ha un built-in per generarne uno. Quindi ne generiamo uno dalla prima colonna ( #&@@@#) e dalla prima riga ( #&@@#) dell'input e controlliamo se è uguale all'input. Per convertire il True/ Falserisultato in 1/ -1usiamo Boole(per dare 1o 0) e poi semplicemente trasformiamo il risultato con 2x-1.


6

Ottava , 30 byte

Presumo che non debba gestire matrici 1.000.000x1.000.000 come si dice nella sfida. Funziona con matrici che non superano la memoria disponibile (nel mio caso meno di 1 TB).

@(x)x==toeplitz(x(:,1),x(1,:))

Provalo online!

Questo prende una matrice xcome input e crea una matrice di Toeplitz in base ai valori sulla prima colonna e sulla prima riga. Controllerà quindi ogni elemento delle matrici per l'uguaglianza. SE tutti gli elementi sono uguali, allora l'ingresso è una matrice di Toeplitz.

L'output sarà una matrice delle stesse dimensioni dell'input. Se ci sono degli zeri nell'output, questo è considerato erroneamente Ottava.

Modificare:

Ho appena notato il formato di output rigoroso:

Questo funziona per 41 byte. Potrebbe essere possibile giocare a golf a uno o due byte da questa versione, ma spero che le regole di output saranno un po 'allentate.

@(x)2*(0||(x==toeplitz(x(:,1),x(1,:))))-1


5

05AB1E , 11 byte

Œ2ùvy`¦s¨QP

Provalo online!

Spiegazione

Œ             # get all sublists of input
 2ù           # keep only those of length 2
   v          # for each such pair
    y`        # split to separate lists
      ¦       # remove the first element of the second list
       s¨     # remove the last element of the first list
         Q    # compare for equality
          P   # product of stack

4

Haskell , 43 byte

f(a:b:t)|init a==tail b=f$b:t|1>0= -1
f _=1

Provalo online!


Dang, complicandolo di nuovo. Curiosamente, lo ottengo fino a 39 byte con output di verità / falsa, quindi se Toeplitz = Falsefosse consentito avrei potuto batterlo di un byte.
Ørjan Johansen,

3

Mathematica, 94 byte

l=Length;If[l@Flatten[Union/@Table[#~Diagonal~k,{k,-l@#+1,l@#[[1]]-1}]]==l@#+l@#[[1]]-1,1,-1]&

ingresso

{{6, 7, 8, 9, 2}, {4, 6, 7, 8, 9}, {1, 4, 6, 7, 8}, {0, 1, 4, 6, 7}}

un altro basato sull'algoritmo di Stewie Griffin

Mathematica, 44 byte

If[#==#[[;;,1]]~ToeplitzMatrix~#[[1]],1,-1]&

2
Devi definire s? Non puoi semplicemente usare #invece?
Non un albero

sì! hai ragione!
J42161217

3

Java 7, 239 233 220 113 byte

int c(int[][]a){for(int i=a.length,j;i-->1;)for(j=a[0].length;j-->1;)if(a[i][j]!=a[i-1][j-1])return -1;return 1;}

-107 byte dopo una punta di utilizzo di un algoritmo più efficiente grazie a @Neil .

Spiegazione:

Provalo qui.

int c(int[][]a){                // Method with integer-matrix parameter and integer return-type
  for(int i=a.length,j;i-->1;)  //  Loop over the rows (excluding the first)
    for(j=a[0].length;j-->1;)   //   Loop over the columns (excluding the first)
      if(a[i][j]!=a[i-1][j-1])  //    If the current cell doesn't equal the one top-left of it:
        return -1;              //     Return -1
                                //   End of columns loop (implicit / single-line body)
                                //  End of rows loop (implicit / single-line body)
  return 1;                     //  Return 1
}                               // End of method

che cos'è r & c in prima funzione?
Mickey Jack,

@MickeyJack Righe e colonne ( r= ne c= mse lo confronti con la sfida).
Kevin Cruijssen

Non dovresti passare l'array come parametro alla funzione? Inoltre, esiste un algoritmo molto più efficiente per questo, che ridurrebbe il conteggio dei byte di circa il 50%.
Neil,

1
@KevinCruijssen Basta controllare che tutti gli elementi non nella prima riga o colonna siano uguali all'elemento in diagonale verso l'alto e a sinistra da esso.
Neil,

1
Ah, devi persino usare l' -->operatore!
Neil,

3

Haskell , 51 byte

t prende un elenco di elenchi di numeri interi e restituisce un numero intero.

t m=1-sum[2|or$zipWith((.init).(/=).tail)=<<tail$m]

Provalo online!

Potrebbero essere stati 39 o 38 byte con output di verità / falsa.

L'idea da utilizzare è initstata ispirata dalla risposta 05AB1E di Emigna, che utilizza un metodo molto simile; prima di allora ho usato una compressione annidata.

Come funziona

  • zipWith((.init).(/=).tail)=<<tailè una forma senza punti di \m->zipWith(\x y->tail x/=init y)(tail m)m.
  • Questo combina ogni coppia consecutiva di file di m , verificando se il primo con il primo elemento rimosso è diverso dal secondo con il secondo elemento rimosso.
  • L' orpoi combina i controlli per tutte le coppie di righe.
  • 1-sum[2|...] converte il formato di output.

2

JavaScript (ES6), 65 54 byte

a=>a.some((b,i)=>i--&&b.some((c,j)=>c-a[i][j-1]))?-1:1

O usando il tuo trucco : a=>a.some(b=>b.some((v,i)=>d[i]-(d[i]=v),d=[,...d]),d=[])?-1:1(62 byte)
Arnauld,

1
@Arnauld Grazie, ma a quanto pare stavo ripensando di nuovo al problema ...
Neil,

2

Rubino , 54 byte

->a,b,m{m.reduce{|x,y|x[0..-2]==y[1,b]?y:[]}.size<=>1}

Esattamente come specificato, può essere golfato di più se si accetta input / output flessibile.

Spiegazione:

Scorrere sulla matrice e confrontare ogni riga con la riga sopra, spostata di una a destra. Se sono diversi, utilizzare un array vuoto per la successiva iterazione. Alla fine, restituisce -1 se l'array finale è vuoto o 1 se sono almeno 2 elementi (poiché la matrice più piccola possibile è 3x3, ciò è vero se tutti i confronti restituiscono true)

Provalo online!


Buon uso di <=>per calcolare il risultato!
Neil,

Che ne dici |(*x,_),y|quindi non è necessario tagliare x?
Stefan Pochmann,

1

PHP, 70 byte

<?=!preg_match('/\[([\d,]+?),\d+\],\[\d+,(?!\1)/',json_encode($_GET));

1

Python, 108

r=range
f=lambda x,n,m:all([len(set([x[i][j] for i in r(n) for j in r(m) if j-i==k]))==1 for k in r(1-n,m)])

Non è affatto efficiente poiché tocca ogni elemento n+mvolte mentre filtra per le diagonali. Quindi controlla se ci sono più di un elemento univoco per diagonale.


1

Assioma, 121 byte

f(m)==(r:=nrows(m);c:=ncols(m);for i in 1..r-1 repeat for j in 1..c-1 repeat if m(i,j)~=m(i+1,j+1)then return false;true)

m deve essere una matrice di alcuni elementi che consentono ~ =; Ungolf esso

f m ==
  r := nrows(m)
  c := ncols(m)
  for i in 1..(r - 1) repeat
    for j in 1..(c - 1) repeat
      if m(i,j)~=m(i + 1,j + 1)     then return(false)
  true

1

Retina , 148 byte

m(1`\d+
$*#
1`#\n\d+\n
@
+`(#*)#@([^#\n]*(#*)\n)(.*)$
$1# $2$1@$4 #$3
@

+`##
# #
+(+s`^(\d+)\b(.*)^\1\b
$1$2#
s`.*^\d.*^\d.*
-1
)%`^[^- ]+ ?

\s+
1

Provalo online!

Una matrice di input N × M

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

viene prima convertito in una matrice N × (N + M-1) allineando le diagonali in questo modo:

# # # 6 7 8 9 2 0
# # 4 6 7 8 9 2 #
# 1 4 6 7 8 9 # #
0 1 4 6 7 8 # # #

e quindi la prima colonna viene ripetutamente controllata per contenere un singolo numero univoco, e rimossa in questo caso. La matrice è Toeplitz se l'output è vuoto.


Oh, non funziona con numeri negativi, devo sistemare questo :)
eush77,

1

MATL , 11 byte

T&Xd"@Xz&=v

Provalo online!

Il semplice metodo "costruisci una matrice di Toeplitz e verifica contro di essa", che usano le prime risposte, mi sembrava in qualche modo noioso (e sembra che sarebbe comunque più lungo di 1 byte). Quindi ho optato per il metodo "controlla che ogni diagonale contenga solo un valore univoco".

T&Xd - Estrai le diagonali dell'input e crea una nuova matrice con esse come colonne (riempimento con zeri secondo necessità)

" - iterare attraverso le colonne di quello

@Xz - spingere la variabile di iterazione (la colonna corrente) e rimuovere gli zeri (riempimento) da essa

&=- controllo dell'uguaglianza di trasmissione : crea una matrice con tutti gli 1 (verità) se tutti i valori rimanenti sono uguali tra loro, altrimenti la matrice contiene alcuni 0 che sono falsi

v - concatena i valori del risultato insieme, per creare un vettore del risultato finale che è o verità (tutti gli 1) o falso (alcuni 0)



0

Clojure, 94 byte

#(if(=(+ %2 %3 -1)(count(set(for[Z[zipmap][i r](Z(range)%)[j v](Z(range)r)][(- i j)v]))))1 -1)
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.