Vérifiez si une matrice est une matrice de Toeplitz

11

Vous recevrez un tableau à deux dimensions et un nombre et vous devrez déterminer si la matrice donnée est Toeplitz ou non.

Format d'entrée:

Vous recevrez une fonction qui prendra la two-dimensionalmatrice comme argument.

Format de sortie:

Retour 1de la fonction si la matrice est Toeplitz , sinon retour -1.

Contraintes:

3 < n,m < 10,000,000

nest le nombre de lignes tandis que msera le nombre de colonnes.

Exemple de scénario de 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 

Notation

Il s'agit de , donc la réponse la plus courte en octets l'emporte.

Martin Ender
la source
8
C'est un bon défi, mais nous préférons ici les exigences d'E / S laxistes. Je suggère d'autoriser à la fois les programmes et les fonctions comme c'est le cas par défaut . Et pour autoriser True / False ou 1/0 comme sorties, ou peut-être juste deux sorties distinctes cohérentes comme cela semble être préféré pour les problèmes de décision.
2017 à 17h59
15
En outre, une définition de Toeplitz serait bonne, de même que davantage de cas de test, y compris ceux non-Toeplitz. Vous ne savez pas ce que vous voulez dire sur l'ajout de code.
2017
5
Je pense que vous devez réduire la valeur maximale de n, m . Sinon, l'essentiel de ce défi est de trouver un moyen de traiter une matrice de 1 téraoctet.
Stewie Griffin
1
Les éléments de la matrice seront-ils toujours des entiers non négatifs?
Martin Ender

Réponses:

7

Mathematica, 42 octets

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

Mathematica n'a pas de fonction intégrée pour vérifier si quelque chose est une matrice Toeplitz, mais il en possède une pour en générer une. Nous en générons donc une à partir de la première colonne ( #&@@@#) et de la première ligne ( #&@@#) de l'entrée et vérifions si elle est égale à l'entrée. Pour convertir le True/ Falserésultat en 1/ -1nous utilisons Boole(pour donner 1ou 0), puis transformons simplement le résultat avec 2x-1.

Martin Ender
la source
6

Octave , 30 octets

Je suppose que je n'ai pas à gérer des matrices de 1 000 000 x 1 000 000 comme il est dit dans le défi. Cela fonctionne pour les matrices qui ne dépassent pas la mémoire disponible (moins de 1 To dans mon cas).

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

Essayez-le en ligne!

Cela prend une matrice xen entrée et crée une matrice Toeplitz basée sur les valeurs de la première colonne et de la première ligne. Il vérifiera ensuite l'égalité de chaque élément des matrices. SI tous les éléments sont égaux, l'entrée est une matrice de Toeplitz.

La sortie sera une matrice des mêmes dimensions que l'entrée. S'il y a des zéros dans la sortie, cela est considéré comme un octave.

Éditer:

Je viens de remarquer le format de sortie strict:

Cela fonctionne pour 41 octets. Il pourrait être possible de jouer un ou deux octets à partir de cette version, mais j'espère que les règles de sortie seront un peu assouplies.

@(x)2*(0||(x==toeplitz(x(:,1),x(1,:))))-1
Stewie Griffin
la source
5

Gelée , 5 octets

ŒDE€Ạ

Essayez-le en ligne!

En suivant la définition ici .

ŒDE€Ạ
ŒD     all diagonals
   €   for each diagonal ...
  E       all elements are equal
    Ạ  all diagonal return true
Leaky Nun
la source
5

05AB1E , 11 octets

Œ2ùvy`¦s¨QP

Essayez-le en ligne!

Explication

Œ             # 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
Emigna
la source
4

Haskell , 43 octets

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

Essayez-le en ligne!

xnor
la source
Dang, la compliquant de nouveau. Curieusement, je descends à 39 octets avec une sortie vérité / fausse, donc si Toeplitz = Falseétait autorisé, j'aurais pu le battre d'un octet.
Ørjan Johansen
3

Mathematica, 94 octets

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

contribution

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

un autre basé sur l' algorithme de Stewie Griffin

Mathematica, 44 octets

If[#==#[[;;,1]]~ToeplitzMatrix~#[[1]],1,-1]&
J42161217
la source
2
Avez-vous besoin de définir s? Ne pouvez-vous pas simplement utiliser à la #place?
Pas un arbre
Oui! tu as raison!
J42161217
3

Java 7, 239 233 220 113 octets

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 octets après une astuce d'utilisation d'un algorithme plus efficace grâce à @Neil .

Explication:

Essayez-le ici.

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
Kevin Cruijssen
la source
qu'est-ce que la r & c dans la première fonction?
Mickey Jack
@MickeyJack Lignes et colonnes ( r= net c= msi vous les comparez au défi).
Kevin Cruijssen
Ne devriez-vous pas passer le tableau en tant que paramètre à la fonction? En outre, il existe un algorithme beaucoup plus efficace pour cela, qui réduirait votre nombre d'octets d'environ 50%.
Neil
1
@KevinCruijssen Vérifiez simplement que tous les éléments qui ne se trouvent pas dans la première ligne ou colonne sont égaux à l'élément en diagonale vers le haut et à gauche de celui-ci.
Neil
1
Ah, vous devez même utiliser l' -->opérateur!
Neil
3

Haskell , 51 octets

t prend une liste de listes d'entiers et retourne un entier.

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

Essayez-le en ligne!

Cela aurait pu être de 39 ou 38 octets avec une sortie vérité / fausse.

L'idée à utiliser initest inspirée de la réponse 05AB1E d'Emigna, qui utilise une méthode très similaire; avant cela, j'ai utilisé un zip imbriqué.

Comment ça fonctionne

  • zipWith((.init).(/=).tail)=<<tailest une forme sans point de \m->zipWith(\x y->tail x/=init y)(tail m)m.
  • Ceci combine chaque paire consécutive de rangées de m, vérifiant si le premier avec le premier élément supprimé est différent du second avec le deuxième élément supprimé.
  • Le orcombine ensuite les contrôles pour toutes les paires de lignes.
  • 1-sum[2|...] convertit le format de sortie.
Ørjan Johansen
la source
2

JavaScript (ES6), 65 54 octets

a=>a.some((b,i)=>i--&&b.some((c,j)=>c-a[i][j-1]))?-1:1
Neil
la source
Ou en utilisant votre propre astuce : a=>a.some(b=>b.some((v,i)=>d[i]-(d[i]=v),d=[,...d]),d=[])?-1:1(62 octets)
Arnauld
1
@Arnauld Merci, mais il s'avère que je repensais de nouveau au problème ...
Neil
2

Rubis , 54 octets

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

Exactement comme spécifié, peut être joué plus si une entrée / sortie flexible est acceptée.

Explication:

Itérer sur la matrice et comparer chaque ligne avec la ligne ci-dessus, décalée de un vers la droite. S'ils sont différents, utilisez un tableau vide pour la prochaine itération. À la fin, retournez -1 si le tableau final est vide, ou 1 si c'est au moins 2 éléments (puisque la plus petite matrice possible est 3x3, cela est vrai si toutes les comparaisons retournent vrai)

Essayez-le en ligne!

GB
la source
Belle utilisation de <=>pour calculer le résultat!
Neil
Que diriez - vous |(*x,_),y|si vous ne avez pas besoin de tranche x?
Stefan Pochmann
1

PHP, 70 octets

<?=!preg_match('/\[([\d,]+?),\d+\],\[\d+,(?!\1)/',json_encode($_GET));
user63956
la source
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)])

Pas efficace du tout car il touche tous les n+mtemps des éléments lors du filtrage des diagonales. Vérifie ensuite s'il y a plus d'un élément unique par diagonale.

DenDenDo
la source
1

Axiome, 121 octets

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 doit être une matrice d'un élément qui permet ~ =; le défouler

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
RosLuP
la source
1

Rétine , 148 octets

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

Essayez-le en ligne!

Une matrice d'entrée 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

est d'abord converti en une matrice N × (N + M-1) en alignant les diagonales de cette façon:

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

puis la première colonne est vérifiée à plusieurs reprises pour contenir un seul numéro unique et supprimée si tel est le cas. La matrice est Toeplitz si la sortie est vierge.

eush77
la source
Oh, cela ne fonctionne pas avec des nombres négatifs,
je
1

MATL , 11 octets

T&Xd"@Xz&=v

Essayez-le en ligne!

La méthode simple «construire une matrice de Toeplitz et vérifier par rapport à elle», que les premières réponses utilisent, me semblait en quelque sorte ennuyeuse (et il semble que ce serait de 1 octet de plus de toute façon). J'ai donc opté pour la méthode "vérifier que chaque diagonale ne contient qu'une seule valeur".

T&Xd - Extraire les diagonales de l'entrée et créer une nouvelle matrice avec elles sous forme de colonnes (remplissage avec des zéros au besoin)

" - parcourir les colonnes de ce

@Xz - poussez la variable d'itération (la colonne courante), et supprimez-y (remplissage) les zéros

&=- vérification de l'égalité de diffusion - cela crée une matrice avec tous les 1 (véridique) si toutes les valeurs restantes sont égales les unes aux autres, sinon la matrice contient quelques 0, ce qui est faux

v - concaténer les valeurs de résultat ensemble, pour créer un vecteur de résultat final qui soit véridique (tous les 1) ou falsey (certains 0)

Sundar - Rétablir Monica
la source
0

R , 48 octets

pryr::f(all(x[-1,-1]==x[-nrow(x),-ncol(x)])*2-1)

Essayez-le en ligne!

Nitrodon
la source
0

Clojure, 94 octets

#(if(=(+ %2 %3 -1)(count(set(for[Z[zipmap][i r](Z(range)%)[j v](Z(range)r)][(- i j)v]))))1 -1)
NikoNyrh
la source